题目链接:http://noi.openjudge.cn/ch0205/7218/
- 总时间限制: 100ms 内存限制: 65536kB
- 描述
-
阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个R×C的字符矩阵来表示。字符S表示阿尔吉侬所在的位置,字符E表示奶酪所在的位置,字符#表示墙壁,字符.表示可以通行。阿尔吉侬在1个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。
- 输入
- 第一行是一个正整数T(1 <= T <= 10),表示一共有T组数据。
每一组数据的第一行包含了两个用空格分开的正整数R和C(2 <= R, C <= 200),表示地图是一个R×C的矩阵。
接下来的R行描述了地图的具体内容,每一行包含了C个字符。字符含义如题目描述中所述。保证有且仅有一个S和E。 - 输出
- 对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。每组数据的输出结果占一行。
- 样例输入
-
3 3 4 .S.. ###. ..E. 3 4 .S.. .E.. .... 3 4 .S.. #### ..E.
- 样例输出
-
5 1 oop!
算法分析:广搜。
代码一:使用C++ STL的队列
1 #include<stdio.h> 2 #include<iostream> 3 #include<queue> 4 using namespace std; 5 6 struct obj 7 { 8 int xx,yy,step;//step表示到达(xx,yy)这个点所需要的最少步数 9 }; 10 11 int T,R,C; 12 char map[202][202]; 13 queue<struct obj> q; 14 struct obj S,E;//起点和终点 15 16 int dx[4]={-1,0,1,0};//上右下左 17 int dy[4]={0,1,0,-1}; 18 void BFS(); 19 20 int main(int argc, char *argv[]) 21 { 22 int i,j; 23 char cccc; 24 //freopen("7218.in","r",stdin); 25 26 scanf("%d",&T); 27 while(T) 28 { 29 T--; 30 scanf("%d%d",&R,&C); 31 while ((cccc = getchar()) != EOF && cccc != '\n'); 32 //不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止 33 34 for(i=0;i<R;i++) 35 { 36 for(j=0;j<C;j++) 37 { 38 //map[i][j]=getchar(); 39 scanf("%c",&map[i][j]); 40 if(map[i][j]=='S') 41 { S.xx=i; S.yy=j; S.step=0; } 42 else if(map[i][j]=='E') 43 { E.xx=i; E.yy=j; E.step=-1; map[i][j]='.'; } 44 } 45 while ((cccc = getchar()) != EOF && cccc != '\n'); 46 //不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止 47 } 48 49 BFS(); 50 51 if(E.step==-1) printf("oop!\n"); 52 else printf("%d\n",E.step); 53 } 54 return 0; 55 } 56 57 void BFS() 58 { 59 int i,txx,tyy; 60 struct obj temp; 61 62 while(!q.empty()) q.pop(); 63 64 q.push(S); 65 while(!q.empty()) 66 { 67 for(i=0;i<4;i++) 68 { 69 txx=q.front().xx+dx[i]; 70 tyy=q.front().yy+dy[i]; 71 if(txx>=0&&txx<R&&tyy>=0&&tyy<C&&map[txx][tyy]=='.') 72 { 73 temp.xx=txx; 74 temp.yy=tyy; 75 temp.step=q.front().step+1; 76 map[txx][tyy]='#'; 77 q.push(temp); 78 if(temp.xx==E.xx&&temp.yy==E.yy) 79 { 80 E.step=temp.step; 81 return ; 82 } 83 } 84 } 85 q.pop(); 86 } 87 }
代码二:不使用系统队列,自己模拟队列。
1 //来源: http://blog.csdn.net/wanglinlin_bfcx/article/details/75670392 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 struct obj 6 { 7 int x,y,step; 8 }; 9 10 int T,R,C; 11 char a[201][201]; 12 int ans,sx,sy,ex,ey; 13 struct obj que[40001];//que[]是广搜队列 14 int dx[4]={-1,1,0,0};//上下右左 15 int dy[4]={0,0,1,-1}; 16 17 void bfs() 18 { 19 que[0].x=sx,que[0].y=sy,que[0].step=1; 20 int i,t=0,w=1;//t是队列头,w是队列尾 21 while(t<w) 22 { 23 for(i=0;i<4;i++) 24 { 25 int xx=que[t].x+dx[i];int yy=que[t].y+dy[i]; 26 if(xx>=0&&xx<R&&yy>=0&&yy<C) 27 { 28 if(xx==ex&&yy==ey) 29 { 30 ans=que[t].step;return; 31 } 32 if(a[xx][yy]=='.') 33 a[xx][yy]='#',que[w].x=xx,que[w].y=yy,que[w].step=que[t].step+1,w++; 34 } 35 } 36 t++; 37 } 38 } 39 int main() 40 { 41 int i,j; 42 freopen("7218.in","r",stdin); 43 cin>>T; 44 while(T--) 45 { 46 cin>>R>>C; 47 ans=-1; 48 memset(a,0,sizeof(a)); 49 for(i=0;i<R;i++) 50 for(j=0;j<C;j++) 51 { 52 cin>>a[i][j]; 53 if(a[i][j]=='S') sx=i,sy=j; 54 if(a[i][j]=='E') ex=i,ey=j; 55 } 56 bfs(); 57 if(ans==-1) cout<<"oop!"<<endl; 58 else cout<<ans<<endl; 59 } 60 }