信息学奥赛一本通 1216:红与黑 | OpenJudge NOI 2.5 1818:红与黑

news/2024/11/17 19:44:27/

【题目链接】

ybt 1216:红与黑
OpenJudge NOI 2.5 1818:红与黑

【题目考点】

1. 搜索 连通块问题

【解题思路】

1. 深搜

从第一个格子出发,遍历所有可以前进的方向,前进到下一个格后,再遍历可以前进的方向,走过的格子做标记,标记过的格子就不走了,不是黑色的格子不走。如果没有可以走的格子,那么退回到上一位置,看其它前进方向的格子可不可以走。
每走一个格子,格子计数加1,如果退回,也不减少格子计数。深搜结束后,输出格子计数。

2. 广搜

将起始位置做标记,而后入队。每出队一个位置,看看能从这个位置走到哪些位置,可以走到的位置必须满足3个条件:在地图内,没标记过,是黑色格子。将能从该位置走到的位置做标记,而后入队。继续出队一个位置,循环此过程,直到队空。
每标记一个位置,格子计数加1。广搜结束后,输出格子计数。

【注意】:该题中,w表示宽度,也就是列数。h表示高度,也就是行数。这是一个h行w列的矩阵。

【题解代码】

解法1:深搜

#include <bits/stdc++.h>
using namespace std;
#define N 25
char mp[N][N];//地图
int w, h, ct;//h:行数,w:ct:结果计数
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//方向数组
bool vis[N][N];
void dfs(int sx, int sy)
{for(int i = 0; i < 4; ++i){int x = sx + dir[i][0], y = sy + dir[i][1];if(x >= 1 && x <= h && y >= 1 && y <= w && vis[x][y] == false && mp[x][y] != '#'){ct++;vis[x][y] = true;dfs(x, y);}}
}
int main()
{int stx, sty;//起始位置while(true){cin >> w >> h;if(w == 0 && h == 0)return 0;for(int i = 1; i <= h; ++i)for(int j = 1; j <= w; ++j){cin >> mp[i][j];if(mp[i][j] == '@')stx = i, sty = j;}memset(vis, 0, sizeof(vis));//多组数据,注意状态还原ct = 1;vis[stx][sty] = true;dfs(stx, sty);cout << ct << endl;}return 0;
}

解法2:广搜

#include <bits/stdc++.h>
using namespace std;
#define N 25
struct Node
{int x, y;Node(){}Node(int a, int b):x(a),y(b){}
};
char mp[N][N];//地图
int w, h;//w:列数 h:行数
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//方向数组
bool vis[N][N];
int bfs(int sx, int sy)//传入起始位置
{queue<Node> que;vis[sx][sy] = true;que.push(Node(sx, sy));int ct = 1;//计数,看可以到达几个黑色格子while(que.empty() == false){Node u = que.front();que.pop();for(int i = 0; i < 4; ++i){int x = u.x + dir[i][0], y = u.y + dir[i][1];if(x >= 1 && x <= h && y >= 1 && y <= w && vis[x][y] == false && mp[x][y] != '#'){vis[x][y] = true;que.push(Node(x, y));ct++;}}}return ct;
}
int main()
{int stx, sty;while(true){cin >> w >> h;if(w == 0 && h == 0)return 0;for(int i = 1; i <= h; ++i)for(int j = 1; j <= w; ++j){cin >> mp[i][j];if(mp[i][j] == '@')stx = i, sty = j;}memset(vis, 0, sizeof(vis));cout << bfs(stx, sty) << endl;}return 0;
}

http://www.ppmy.cn/news/167114.html

相关文章

【DP 入门 洛谷P1216 数字三角形】

DP 入门 洛谷P1216 数字三角形 数字三角形1. DP 从下往上推2 从上往下推 找出最后一行最大值3记忆化搜索 数字三角形 题目链接 1. DP 从下往上推 import java.util.Scanner;public class P1216 {public static void main(String[] args) {Scanner kbnew Scanner(System.in);i…

cf 1216a

https://codeforc.es/problemset/problem/1216/A 本题直接$O(n)$贪心。 1 #include<bits/stdc.h>2 using namespace std; 3 int const N20000010; 4 char s[N]; 5 int main(){6 int n,ans0,num0; 7 scanf("%d%s",&n,s1); 8 for(int i…

hrbust 1216

数的划分 Time Limit: 1000 MS Memory Limit: 65535 K Total Submit: 184(89 users) Total Accepted: 125(87 users) Rating: Special Judge: No Description 将整数n分成k份&#xff0c;且每份不能为空&#xff0c;任意两份不能相同(不考虑顺序)。 例如&#xff1a;n7&am…

zoj1216

题目大意&#xff1a; 一张牌可以被放在桌子上&#xff0c;短边和桌子平行&#xff0c;这样最多可以有长度的一半架空在桌子上&#xff0c;如果架空更多长度&#xff0c;那么牌就会掉在地上。 两张牌最多可以架空3/4&#xff0c;第一张架空底部牌1/2&#xff0c;底部牌最多架…

cf 1216e1

https://codeforc.es/problemset/problem/1216/E1 求1121231234...序列里面第k个数字&#xff0c;k不超过10亿。 我们只要预处理一个sum数组&#xff0c;然后每次二分一下&#xff08;其实不二分也可以&#xff09; 1 #include <bits/stdc.h>2 using namespace std;3 i…

信息学奥赛一本通1216:红与黑题解

【题目描述】 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻的黑色瓷砖移动。请写一个程序&#xff0c;计算你总共能够到达多少块黑色的瓷砖。 【输入】 包括多组数据。每组数据的第一行是两个…

cf 1216c

https://codeforc.es/problemset/problem/1216/C 判断一个矩形是否被另外两个矩形完全覆盖&#xff0c;这题是我是用离散化的方法来做的。 1 #include<bits/stdc.h>2 using namespace std; 3 int x[7],y[7],tx[7],ty[7]; 4 int inner(int x1,int y1,int x2,int…

cf 1216f

https://codeforc.es/problemset/problem/1216/F 有直线上n个位置&#xff0c;每个位置上可以花费i的代价使得联网&#xff0c;某些位置可以放置路由器&#xff0c;放路由器的代价也是i&#xff0c;放置了路由器以后&#xff0c;可以让[i-k,ik]的范围内上网&#xff0c;要求每台…