H.YXY的迷宫
时间限制: C/C++ 10000ms; Java 20000ms 内存限制: 65535KB
通过次数: 11 总提交次数: 28
问题描述
YXY给出了一个仅由数字0与1组成的n*n的迷宫,你可以站在这个迷宫的某一格上,若你当前所处位置为数字0,那么你可以移动到相邻4个方向(上下左右)上数字为1的格子上。同样若你当前所处位置为数字1,那么你可以移动到相邻4个方向上数字为0的格子上。对于迷宫的一个格子,询问由这一格可以到达的格子的总数是多少(包括自身的初始位置)。
输入描述
第一行输入两个正整数n和m。n表示将要输入的迷宫为n*n,m表示共有m次询问。(保证1<=n<=1000,1<=m<=100000)
接下来输入n行,每行输入n个字符。(输入保证字符均为为0或1,字符之间没有空格)
接下来输入m行,每行输入两个正整数i,j。表示询问从第i行第j列这个格子出发,一共能够到达格子的总数。
输出描述
输出共m行,每行输出一个数表示对应询问的答案。
样例输入
2 2 01 10 1 1 2 2
样例输出
4 4
来源
中北大学2018年新生赛
提示
样例解释:
对于
01
10
这个迷宫
左上角的0(第1行第1列)可以首先可以到达两个1(第1行第2列)(第2行第1列)的位置,然后这两个1又都可以到达两个0(第1行第1列)(第2行第2列)的位置。
所以从(1,1)出发,可以到达的格子总数为4
新生赛的一道题目,下来发现这个题是真的简单,真的水,当时想的是遍历每个格子,求每个格子联通块的数量,又不知道怎么标记,看了题解,我真的发自内心的嘲笑自己。
#include<cstdio> #include<cstring> using namespace std; const int maxn=1010; int ans[100100]; char maze[maxn][maxn]; int n,m,cnt,lay=1; int vis[maxn][maxn],visit[100100]; int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; void dfs(int x, int y, int cur) { vis[x][y] = lay; visit[lay] = ++cnt; for (int i = 0; i < 4; ++i) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if (xx < 0 || xx >= n || yy < 0 || yy >= n || vis[xx][yy] == lay) continue; int next = maze[xx][yy] - '0'; if (next == !cur) { dfs(xx, yy, next); } } } int main() { memset(visit,-1,sizeof(visit)); int top=0; scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",maze[i]); for(int i=0; i<m; i++) { int x,y; scanf("%d%d",&x,&y); if(visit[vis[x-1][y-1]]==-1) { dfs(x-1,y-1,maze[x-1][y-1]-'0'); ans[top++]=visit[vis[x-1][y-1]]; } else { ans[top++]=visit[vis[x-1][y-1]]; } cnt=0; lay++; printf("%d\n",ans[i]); } } 文章来源: DFS迷宫