B – Help the Princess!
一个n * m的地图,有个若干坏蛋和主角,主角需要到达出口才能得救,主角和坏蛋每秒都可以选择往四周走或者停留不动,求主角是否存在一条路径到达出口,这条路径无论坏蛋怎么走都无法阻断!
思路:先用坏蛋去bfs出到每个位置的最小时间,然后在bfs主角,主角所走的每步的时间都需要<之前bfs的最小时间。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 205;
const int INF = 0x3f3f3f3f;
char mp[maxn][maxn];
int tim[maxn][maxn], vis[maxn][maxn], H, W;
pair < int, int > Q[maxn * maxn * 2];
int head, tail;
int dir[4][2] = {
0, 1, 1, 0, 0, -1, -1, 0
};
bool InMap(int x, int y){
return 1 <= x && x <= H && 1 <= y && y <= W;
}
void bfs1(){
head = tail = 0;
for(int i = 1; i <= H; i++)
for(int j = 1; j <= W; j++){
tim[i][j] = INF;
if(mp[i][j] == '$'){
Q[tail++] = make_pair(i, j);
tim[i][j] = 0;
}
}
while(head != tail){
int x = Q[head].first;
int y = Q[head].second;
head++;
for(int i = 0; i < 4; i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(InMap(nx, ny) && mp[nx][ny] != '#' && tim[nx][ny] == INF){
tim[nx][ny] = tim[x][y] + 1;
Q[tail++] = make_pair(nx, ny);
}
}
}
}
bool bfs2(int x, int y){
head = tail = 0;
for(int i = 1; i <= H; i++)
for(int j = 1; j <= W; j++)
vis[i][j] = INF;
vis[x][y] = 0;
Q[tail++] = make_pair(x, y);
while(head != tail){
x = Q[head].first;
y = Q[head].second;
head++;
if(mp[x][y] == '%') return true;
for(int i = 0; i < 4; i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(InMap(nx, ny) && mp[nx][ny] != '#' && vis[nx][ny] == INF){
vis[nx][ny] = vis[x][y] + 1;
if(vis[nx][ny] < tim[nx][ny])
Q[tail++] = make_pair(nx, ny);
}
}
}
return false;
}
int main(){
while(scanf("%d%d", &H, &W) != EOF){
for(int i = 1; i <= H; i++)
scanf("%s", mp[i] + 1);
int x, y;
for(int i = 1; i <= H; i++){
for(int j = 1; j <= W; j++){
if(mp[i][j] == '@'){
x = i;
y = j;
}
}
}
bfs1();
puts(bfs2(x, y) ? "Yes" : "No");
}
return 0;
}