题目链接
题目描述
有一个仅由数字
0
0
与组成的
n×n
n
×
n
格迷宫。若你位于一格
0
0
上,那么你可以移动到相邻格中的某一格
1
1
上,同样若你位于一格上,那么你可以移动到相邻
4
4
格中的某一格上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入格式
第
1
1
行为两个正整数。
下面
n
n
行,每行个字符,字符只可能是
0
0
或者,字符之间没有空格。
接下来
m
m
行,每行个用空格分隔的正整数
i
i
,,对应了迷宫中第
i
i
行第列的一个格子,询问从这一格开始能移动到多少格。
输出格式
m
m
行,对于每个询问输出相应答案。
样例
2 2
01
10
1 1
2 2
/**输出
4
4
**/
解题思路:
- 题目本质就是求一个连通分量里面的总个数,采用dfs得到连通分量,利用vis进行标记,复杂度
- 其次注意输入的优化,不然容易 RA 2,8,9,10 R A 2 , 8 , 9 , 10 这几个点。此处参考这位博主的输入优化思路,将原来的
for(int i=1;i<=n;i++){ char str[105]; scanf("%s",str); for(int j=0;j<strlen(str);j++){ map[i][j+1]=str[j]-'0'; } }
优化成:
for(int i=1;i<=n;i++){ scanf("%s",map[i]+1);//下标从1开始 }
代码部分:
#include <iostream> #include<queue> #include<cstdio> #include<cstring> using namespace std; #define N 1010 int vis[N][N]; char map[N][N]; int n,m,num;//连通分量数 int g[][2]={-1,0,0,1,0,-1,1,0}; int node[1000001][2],ans[N][N];//结果 //先计算出所有的情况,再输出特殊情况的值 //求出所有的连通块,连通块内的值即为结果 void dfs(int x,int y){ num++;//连通分量数 node[num][0]=x,node[num][1]=y; for(int i=0;i<4;i++){ int nx=x+g[i][0]; int ny=y+g[i][1]; if(nx<1||nx>n||ny<1||ny>n) continue; if(!vis[nx][ny]&&(map[x][y]!=map[nx][ny])){ vis[nx][ny]=1; dfs(nx,ny); } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%s",map[i]+1);//下标从1开始 } //先求出所有的结果,最后输出(记忆化 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(!vis[i][j]){ vis[i][j]=1; num=0;//连通分量数记为0 dfs(i,j); for(int k=1;k<=num;k++){ ans[node[k][0]][node[k][1]]=num;//连通分量里的个数 } } } } for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",ans[x][y]); } return 0; }