BFS洪水
试题描述:
已经连续下了几天雨,却还是没有停的样子。土豪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个字符,表示地图。
输出:
若能回家,输出一个整数,表示最少回家步数;否则输出“ORZ hzwer!!!”。
输入示例:
3 3
D.*
...
.S.
输出示例:
3
良心输入示例:
50 50 ...SXX...XX...X...XX.XX....X.......X....X.X....*X. .XX.X..XX.X.X..X.X.X...XX.X.....X....X...X.XX....X ..X..X....X.X.X.X.XX....XX...X..XX....X...XXX...XX X.....X..XXX.XX..X.X.X........XXX....X.X..XX..X... X..X.....X......X.......X..X......X.....X.X..X.... ......XXX..X..XX.X.......X..X......X.X.XXX.X..X... ...X...XX.X..X.........X..XX..XX.X..X.X....X..X..X XX.........XX.XXX.XXX...X..X..XXX.XX.X..X...X.X.X. .....X...X..X.X.X.....X.X.X...XX........XX..X..X.. XXXX..XX..X..X..X..XXX..X...X..X.X...X..XX.XX.X... ......X..X....X.........XX..X..X........X.XX...X.X X..XX...X........X........XXXX.XX.........X.X.XXX. .....XXX...X.XXX....X...XX........X...XXXX...X.... .X.XX....XXX...X...X...X.X...XXX...X...X..XX.XX... ...XXX....XXX.....X.X...XX...X.X.XXX.X.XX..X...... .......X..XX.X.X..........X.XX..X..X.XX.XXXX...XX. X...X.X.X.XXX.X..X.XXX..X...X....X.X..X...X..XX..X ..X..X.XX..X.XXX..X...X..X..X..X.X....X..........X XX....X.X.X.XX.....X..XXXX.XX..X....X.....X.....X. .XX.....X.X..X..X.X...X......X....X..X.XX.XX.XX.X. .....X.........X..X.X...X....XX.X...X..X..XX.XX... .X........X..XX..X...X....XX.XXX.XX.X..X...X...XXX ...X.X.XX...X......XX.X.XXX..X.X.XX....XXX.X...X.. ....X.....XX..XX.X.X...X..X.X....X.....XX.XX..XXX. ....X........XXXXXX.........XX..X....XX.XXXX...... ..XX.XXX.X...X.X.X.X..XXXX....X.X.X...XX.X..X..X.. XX..XX.X...X....XX....X.......X..X.X......XXXXX... XX..XX.XX.X..X...XX....XX.X..X...X.X....X......... ..X.....X...X..X.........X......X...XX.XX...X..... X.X..XX.X.X.X.XXXX.X...X..X...XX..X.....X.X.XXX... ..X....X.X.X......X..X...XX..X...X.X.XXX.X....XX.X X.....X.X...XXXXX.....X..XX...X....X...XXX....X... .XXX...XXXX.X....X...XX.XX..X.X........X...X....X. ..XXX.XX....X.XX.X..X...X.X.X.....X...X....X.XXXXX .XX...X.X....XXX......X.....X....X.X..X..X....XX.X XX..XX.X....X...XXX....X..XXX.XXX.X.X....X.X...... XX....X.X....X..X.XX...X..X.X....X..XX...XX...X... X.X...X...X..X....X.X.........X...X...X....X..X... .X...X...X.X....X.....XX......XXX..XX.XX.X.....X.. ..X.X..XX.X..X..........X.X.XX..X..X.X.XXXX....... ..X...XX.X.X..XX..XXXXX...X........XX...X.X..X..XX .....X..XXX....X.XX....XX.XX..XX.X....XX.XX..X.XXX X..X.XX.X.X.......X.X.X..X......X..XX....X.XXX.XXX X..XXXX.........X..X..X............X.X..X..X...X.. X...XX.XX...X........X....X....X.X...X..XD...X..X. ......X.......XXXX..XXX.....X.X.X.X..........X.... X.....XX.XX.XXX.XX.X.X..X.X.......XXXX.....X...XXX .X..XX..X.....XX...XX..X.....XX...X..X....X..X..XX X....XX....XX.....XX.X.XXX....X.......X..X....X..X X.....XX..XX.X.....XX....X..X..X.X.XX.......X..X..
良心输出示例:
86
解题思路:
这是一道神奇的题目,我用了一天。。。。。
首先,我写了一个DFS+BFS,然后结果错误。
接着,改成预处理,创建一个step数组,step[i][j]表示洪水第几步漫道这里。
如:
3 3
D.*
...
.S.
的step是:
-1 1 0
3 2 1
4 3 2
这需要一个BFS
读入·时每遇到一个*就把它丢到队列里面,
然后正常BFS。
预处理以后,就再正常地BFS
然后就好了。
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> using namespace std; int map[51][51]; int step[51][51]; int book[51][51]; int startx, starty; int endx,endy; queue <int> Qx; queue <int> Qy; int n, m; int ans = 0; int wnum = 0; void getstep() { while(!Qx.empty()) { int kx = Qx.front(); int ky = Qy.front(); Qx.pop(); Qy.pop(); if(map[kx-1][ky]==0 && step[kx-1][ky]>step[kx][ky]+1 && kx-1>0) { Qx.push(kx-1); Qy.push(ky); step[kx-1][ky]=step[kx][ky]+1; } if(map[kx+1][ky]==0 && step[kx+1][ky]>step[kx][ky]+1 && kx+1<=n) { Qx.push(kx+1); Qy.push(ky); step[kx+1][ky]=step[kx][ky]+1; } if(map[kx][ky-1]==0 && step[kx][ky-1]>step[kx][ky]+1 && ky-1>0) { Qx.push(kx); Qy.push(ky-1); step[kx][ky-1]=step[kx][ky]+1; } if(map[kx][ky+1]==0 && step[kx][ky+1]>step[kx][ky]+1 && ky+1<=m) { Qx.push(kx); Qy.push(ky+1); step[kx][ky+1]=step[kx][ky]+1; } } } int main() { memset(book,88,sizeof(book)); memset(step,88,sizeof(step)); cin>>n>>m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { char c; cin >> c; if (c == 'S') { startx = i; starty = j; } if (c == '*') { Qx.push(i); Qy.push(j); step[i][j]=0; } if (c == 'D') { endx=i; endy=j; map[i][j]=2; } if (c == 'X') map[i][j] = -1; } getstep(); queue <int> qx; queue <int> qy; qx.push(startx); qy.push(starty); book[startx][starty]=0; while(!qx.empty()) { int kx=qx.front(); int ky=qy.front(); qx.pop(); qy.pop(); if(map[kx][ky]==2) break; if((map[kx-1][ky]==0 || map[kx-1][ky]==2) && book[kx-1][ky]>book[kx][ky]+1 && step[kx-1][ky]>book[kx][ky]+1 && kx-1>=1) { qx.push(kx-1); qy.push(ky); book[kx-1][ky]=book[kx][ky]+1; } if((map[kx+1][ky]==0 || map[kx+1][ky]==2) && book[kx+1][ky]>book[kx][ky]+1 && step[kx+1][ky]>book[kx][ky]+1 && kx+1<=n) { qx.push(kx+1); qy.push(ky); book[kx+1][ky]=book[kx][ky]+1; } if((map[kx][ky+1]==0 || map[kx][ky+1]==2) && book[kx][ky+1]>book[kx][ky]+1 && step[kx][ky+1]>book[kx][ky]+1 && ky+1<=m) { qx.push(kx); qy.push(ky+1); book[kx][ky+1]=book[kx][ky]+1; } if((map[kx][ky-1]==0 || map[kx][ky-1]==2) && book[kx][ky-1]>book[kx][ky]+1 && step[kx][ky-1]>book[kx][ky]+1 && ky-1>=1) { qx.push(kx); qy.push(ky-1); book[kx][ky-1]=book[kx][ky]+1; } } if(book[endx][endy]>=1000000000) cout<<"ORZ hzwer!!!"; else cout<<book[endx][endy]; }