Problem Description
题目原文是英文的,而且比较繁琐。我修饰转述如下:
小强被海盗抓到了,海盗把他和他的船“小强号”关在一个水狱里。
小强拿到了小红给他的一张水狱地图,地图由h行w列字符组成(3 <= h;w <= 500), ,字符共有四种:
S:小强和他的“小强号”的起始位置,他要从这里逃跑。
#:不能逾越的石墙
. : 水道,小强号可以直接通过
@:栅栏水道
已知:
小强打开栅栏需要d分钟 (0 <= d <= 50);
小强号通过单位水道的时间为1分钟;
水狱一定有出口。
输入:
t (一共有t组测试数据)
h w d 以及水狱地图 (每组测试数据输入一次)
输出:
小强出狱的最短时间(和路线)。
Sample Input
2
6 5 7
#####
#S . .#
#@# .#
# . . .#
#@###
# .###
4 5 3
#####
#S# .#
#@ . .#
###@#
Sample Output
16
11
分析:
从S点开始,广度优先搜索,寻找出口。
code广度优先搜索:
1 //code:(普通广度搜索,超时) 2 #include<iostream> 3 #include<queue> 4 using namespace std; 5 #define N 501 6 int h,w,d,sx,sy,t,big,i,j; 7 int tv[N][N]; //到达水域某个位置的最短时间 8 char maze[N][N];//记录水狱的地图 9 int offset[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//可以移动的四个方向 10 struct pos 11 {int x;int y;}; 12 int bfs() 13 { 14 int mymin=big; 15 pos start,temp,temp1; 16 start.x=sx,start.y=sy; 17 tv[sx][sy]=0; 18 19 queue<pos> q; 20 q.push(start); 21 while(!q.empty()) 22 { 23 temp=q.front(); 24 q.pop(); 25 //检测是否逃出水域,更新最短逃出时间 26 if(temp.x==0||temp.x==h-1||temp.y==0||temp.y==w-1) 27 if(mymin>tv[temp.x][temp.y]+1) 28 mymin=tv[temp.x][temp.y]+1; 29 //探索当前位置的下一个位置 30 for(i=0;i<4;i++) 31 { 32 pos temp1;//下一步的位置 33 temp1.x=temp.x+offset[i][0]; 34 temp1.y=temp.y+offset[i][1]; 35 //判断下一步的位置是否超出地图 36 if(temp1.x<0||temp1.x>=h||temp1.y<0||temp1.y>=w) 37 continue; 38 //下一步的位置是水道 39 if(maze[temp1.x][temp1.y]=='.') 40 { 41 if(tv[temp1.x][temp1.y]>tv[temp.x][temp.y]+1) 42 { 43 tv[temp1.x][temp1.y]=tv[temp.x][temp.y]+1; 44 q.push(temp1); 45 } 46 } 47 //下一步的位置是栅栏 48 if(maze[temp1.x][temp1.y]=='@') 49 { 50 if(tv[temp1.x][temp1.y]>tv[temp.x][temp.y]+d+1) 51 { 52 tv[temp1.x][temp1.y]=tv[temp.x][temp.y]+1+d; 53 q.push(temp1); 54 } 55 } 56 } 57 } 58 return mymin; 59 } 60 int main() 61 { 62 cin>>t; 63 while(t--) 64 { 65 cin>>h>>w>>d; 66 big=h*w*d;//逃出水域的时间的上限 67 getchar(); 68 for(i=0;i<h;i++) 69 { 70 for(j=0;j<w;j++) 71 { 72 scanf("%c",&maze[i][j]);//cin>>maze[i][j]; 73 tv[i][j]=big; 74 if(maze[i][j]=='S')//小强出逃的起点位置 75 {sx=i;sy=j;} 76 } 77 getchar(); 78 } 79 printf("%d\n",bfs());//cout<<bfs()<<endl; 80 } 81 //for(;;); 82 }