洛谷P1141 01迷宫
无意中翻到的,很久很久以前没有A的一道题。
记得当时写了近一个小时过不了,绞尽脑汁查错无果,怒点右上角红叉,如今不到十分钟敲完一遍AC。
感触良多呢。即使现在看来是很水的题了,也打算放到博客来,告诉自己:
不知不觉中已经走了很远呢。
当然,前路更长
题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入输出格式
输入格式:输入的第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
输出格式:输出包括m行,对于每个询问输出相应答案。
输入输出样例
输入样例#1:
2 2 01 10 1 1 2 2
输出样例#1:
4 4
说明
所有格子互相可达。
对于20%的数据,n≤10;
对于40%的数据,n≤50;
对于50%的数据,m≤5;
对于60%的数据,n≤100,m≤100;
对于100%的数据,n≤1000,m≤100000。
BFS,队列多开一维(实际是多开了一个数组)存储上一步的数字,以判断是否与当前不同。搜完后从头到尾更新答案。最后统一回答询问。
1 /**/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 const int mxn=2000; 9 int mp[mxn][mxn]; 10 int ans[mxn][mxn]; 11 //bfs 12 int hd=0,tl=0; 13 int qx[900000],qy[900000]; 14 int num[900000]; 15 int mx[5]={0,-1,0,1,0}, 16 my[5]={0,0,-1,0,1}; 17 // 18 int n,m; 19 int bfs(int sx,int sy){ 20 hd=0;tl=1; 21 qx[++hd]=sx;qy[hd]=sy; 22 num[hd]=mp[sx][sy]; 23 int x,y; 24 while(hd<=tl){ 25 x=qx[hd];y=qy[hd]; 26 for(int i=1;i<=4;i++){ 27 int nx=x+mx[i]; 28 int ny=y+my[i]; 29 if(nx>0 && nx<=n && ny>0 && ny<=n && num[hd]!=mp[nx][ny] && !ans[nx][ny]){ 30 qx[++tl]=nx; 31 qy[tl]=ny; 32 num[tl]=mp[nx][ny]; 33 ans[nx][ny]=1; 34 } 35 } 36 hd++; 37 } 38 39 int sum=tl; 40 for(int i=1;i<=tl;i++){ 41 ans[qx[i]][qy[i]]=sum; 42 } 43 return 0; 44 } 45 int main(){ 46 char c[1200]; 47 scanf("%d%d",&n,&m); 48 int i,j; 49 for(i=1;i<=n;i++){ 50 scanf("%s",c); 51 for(j=0;j<n;j++){ 52 mp[i][j+1]=c[j]-'0'; 53 } 54 } 55 for(i=1;i<=n;i++) 56 for(j=1;j<=n;j++){ 57 if(!ans[i][j]){ans[i][j]=1;bfs(i,j);} 58 } 59 int x,y; 60 for(i=1;i<=m;i++){ 61 scanf("%d%d",&x,&y); 62 printf("%d\n",ans[x][y]); 63 } 64 return 0; 65 }
本文为博主原创文章,转载请注明出处。