NOIP模拟赛 水灾
大雨应经下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。
CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。
CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。
求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。
输入文件 sliker.in
输出文件 sliker.out
Input
3 3
D.*
…
.S.
Output
3
Input
3 3
D.*
…
..S
Output
ORZ hzwer!!!
Input
3 6
D…*.
.X.X..
....S.
Output
6
1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 6 const int INF=0x7f7f7f7f; 7 8 int n,m,sx,sy,tx,ty; 9 char map[51][51]; 10 int T[51][51]; 11 int xx[4]={-1,1,0,0}; 12 int yy[4]={0,0,1,-1}; 13 char ch[255]; 14 15 struct data{int x,y,t;}; 16 void bfs1() 17 { 18 queue<data> Q; 19 data p; 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=m;j++) 22 if(map[i][j]=='*') 23 { 24 p=(data){i,j}; 25 T[i][j]=0; 26 Q.push(p); 27 } 28 while(!Q.empty()) 29 { 30 p=Q.front();Q.pop(); 31 for(int i=0;i<4;i++) 32 { 33 int x=p.x+xx[i],y=p.y+yy[i]; 34 if(x<1||x>n||y<1||y>m||T[x][y]!=INF) continue; 35 T[x][y]=T[p.x][p.y]+1; 36 Q.push((data){x,y}); 37 } 38 } 39 } 40 41 void bfs2() 42 { 43 bool vis[51][51],flag=0; 44 memset(vis,0,sizeof(vis)); 45 queue<data> Q; 46 data p={sx,sy,0};vis[sx][sy]=1; 47 Q.push(p); 48 while(!Q.empty()) 49 { 50 p=Q.front();Q.pop(); 51 if(p.x==tx&&p.y==ty) {flag=1;break;} 52 for(int i=0;i<4;i++) 53 { 54 int x=p.x+xx[i],y=p.y+yy[i]; 55 if(x<1||x>n||y<1||y>m||T[x][y]<=p.t+1||vis[x][y]) continue; 56 vis[x][y]=1; 57 Q.push((data){x,y,p.t+1}); 58 } 59 } 60 if(flag) printf("%d\n",p.t); 61 else printf("ORZ hzwer!!!\n"); 62 } 63 64 int main() 65 { 66 scanf("%d %d",&n,&m); 67 memset(T,0x7f,sizeof(T)); 68 for(int i=1;i<=n;i++) 69 { 70 scanf("%s",ch+1); 71 for(int j=1;j<=m;j++) 72 { 73 map[i][j]=ch[j]; 74 switch(map[i][j]) 75 { 76 case 'S': 77 sx=i,sy=j; 78 break; 79 case 'D': 80 tx=i,ty=j; 81 T[i][j]=INF-1; 82 break; 83 case 'X': 84 T[i][j]=0; 85 break; 86 } 87 } 88 } 89 bfs1(); 90 bfs2(); 91 return 0; 92 }
双重bfs