洛谷 P1141 01迷宫 BFS
P1141 01迷宫
题目描述
有一个仅由数字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。
----------------------------------------------------------------------------------------------------------------------------------------------
要想过这道题,需要注意以下两点:
1):每次遍历需进行记忆化处理,减少遍历次数,不容易T;
2):不必要的memset不要开,当一个数组很大时,memset命令很耗时间;
3):在洛谷上运行的程序输入时后面是\r\n两个字符,而程序在本机测试输入时后面只有\n一个字符,所以需要在原来的getchar()后再加个getchar()丢掉剩下的\n,防止对地图的输入造成影响。
1 #include<stdio.h> 2 #include<string.h> 3 int n,m,num,h[3][1000100],u[5]={0,-1,0,1,0},w[5]={0,0,1,0,-1},tap[1010][1010],cu[1000100]; 4 bool map[1010][1010]; 5 int bfs(int,int); 6 int main(){ 7 memset(tap,0,sizeof(tap)); 8 scanf("%d %d",&n,&m); 9 getchar(); 10 getchar(); 11 for(int i=1;i<=n;i++){ 12 for(int j=1;j<=n;j++){ 13 char o; 14 scanf("%c",&o); 15 if(o=='1') map[i][j]=1; 16 else map[i][j]=0; 17 } 18 getchar(); 19 getchar(); 20 } 21 num=0; 22 for(int i=1;i<=m;i++){ 23 int x,y; 24 scanf("%d %d",&x,&y); 25 if(!tap[x][y]){ 26 num++; 27 cu[num]=bfs(x,y); 28 printf("%d\n",cu[num]); 29 } 30 else printf("%d\n",cu[tap[x][y]]); 31 } 32 return 0; 33 } 34 int bfs(int sx,int sy){ 35 int head=0,tail=1; 36 h[1][tail]=sx;h[2][tail]=sy; 37 tap[sx][sy]=num; 38 do{ 39 head++; 40 for(int i=1;i<=4;i++){ 41 int x,y; 42 x=h[1][head]+u[i]; 43 y=h[2][head]+w[i]; 44 if(x>0&&y>0&&x<=n&&y<=n&&(!tap[x][y])) 45 if((map[h[1][head]][h[2][head]]&&!map[x][y])||(!map[h[1][head]][h[2][head]]&&map[x][y])){ 46 tail++; 47 h[1][tail]=x; 48 h[2][tail]=y; 49 tap[x][y]=num; 50 } 51 } 52 }while(head<tail); 53 return tail; 54 }