题目描述
大雨已经下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。
CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D
S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。
CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。
求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。
输入
输入的第一行是两个整数N和M(N,M<=50)。
接下来是一个N行M列的字符矩阵,表示ccy所在城市的地图。
输出
输出仅有一个整数,为ccy回到别墅需要的最少时间。如果无解输出"ORZ hzwer!!!"(不含引号)。
样例输入
3 3
D.*
...
.S.
样例输出
3
题解:首先,洪水到达每个点时间是一定的,先通过一次bfs求出
如果ccy到达某个点的时间>=洪水到达的时间,那么该点不能通过,再来一次bfs就好了
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; typedef pair<int,int> P; int inf; char a[52][52];int XX[5000],YY[5000],tt=0; P que[5000];int h=0,t=0,step[5000],n,m,X,Y; int xx[4]={-1,0,1,0},yy[4]={0,-1,0,1}; int flood[51][51];bool bb[51][51]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%s",a[i]+1); for(int j=1;j<=m;j++) { if(a[i][j]=='*'){que[t].first=i;que[t].second=j;step[t]=0;t++;XX[tt]=i;YY[tt]=j;tt++;} if(a[i][j]=='S'){X=i;Y=j;} } } memset(flood,127,sizeof(flood));inf=flood[0][0]; for(int i=0;i<tt;i++)flood[XX[i]][YY[i]]=0; while(h<t) { int x=que[h].first,y=que[h].second,dx,dy; for(int i=0;i<4;i++) { dx=x+xx[i];dy=y+yy[i]; if(dx<1||dx>n||dy<1||dy>m||a[dx][dy]=='X'||a[dx][dy]=='D')continue; if(flood[dx][dy]==inf) { flood[dx][dy]=step[h]+1;que[t].first=dx;que[t].second=dy;step[t]=step[h]+1;t++; } } h++; } memset(step,0,sizeof(step));memset(que,0,sizeof(que));h=0;t=0; que[t].first=X;que[t].second=Y;step[t]=0;t++; int ans=inf; while(h<t) { int x=que[h].first,y=que[h].second,dx,dy; for(int i=0;i<4;i++) { dx=x+xx[i];dy=y+yy[i]; if(a[dx][dy]=='D'){ans=step[h]+1;h=inf;break;} if(dx<1||dx>n||dy<1||dy>m||a[dx][dy]=='X'||bb[dx][dy])continue; if(step[h]+1>=flood[dx][dy])continue; bb[dx][dy]=1;que[t].first=dx;que[t].second=dy;step[t]=step[h]+1;t++; } h++; } if(ans==inf)puts("ORZ hzwer!!!"); else printf("%d",ans); return 0; }