题意:
小明进入地下迷宫寻找宝藏,找到宝藏后却发生地震,迷宫各处产生岩浆,小明急忙向出口处逃跑。如果丢下宝藏,小明就能迅速离开迷宫,但小明并不想轻易放弃自己的辛苦所得。所以他急忙联系当程序员的朋友你(当然是用手机联系),并告诉你他所面临的情况,希望你能告诉他是否能成功带着宝藏逃脱。
题解:
首先用Spfa预处理出火到达每个位置时间。然后这个人从起点开始bfs,注意一点如果火和人同时到达终点人可以逃脱!!!这个有点坑!手写队列开小了,一直wa。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
void cmax(ll& a,ll b){ if(b>a)a=b; }
void cmin(ll& a,ll b){ if(b<a)a=b; }
void add(int& a,int b,int mod){ a=(a+b)%mod; }
void add(ll& a,ll b,ll mod){ a=(a+b)%mod; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const double eps = 1e-9;
const int maxn = 1005;
int rock[maxn][maxn];
char maze[maxn][maxn];
int Time[maxn][maxn], vis[maxn][maxn];
int n,m;
struct Node{
int x, y;
Node(){}
Node(int a, int b){
x = a;
y = b;
}
};
Node Q[maxn * maxn];
int f, r;
int d[4][2]={
{1, 0},{0, 1},{-1, 0},{0, -1}
};
bool ok(int x, int y){
if(x >= 1 && x <= n && y >= 1 && y <= m)
if(maze[x][y] != '!' && maze[x][y] != '#')
return true;
return false;
}
Node Init(){
scanf("%d %d", &n, &m);
Node s;
memset(rock, 0x3f, sizeof rock);
memset(vis, 0, sizeof vis);
f = r = 0;
for(int i = 1; i <= n; i++){
scanf("%s", maze[i] + 1);
for(int j = 1; j <= m; j++){
if(maze[i][j] == '!'){
Q[r++] = Node(i, j);
vis[i][j] = 1;
rock[i][j] = 0;
}
if(maze[i][j] == 'S')s = Node(i, j);
}
}
Node now;
int x, y;
while(f < r){
now = Q[f++];
vis[now.x][now.y] = 0;
for(int i = 0; i < 4; i++){
x = now.x + d[i][0];
y = now.y + d[i][1];
if(ok(x, y)){
if(rock[now.x][now.y] + 1 < rock[x][y]){
rock[x][y] = rock[now.x][now.y] + 1;
if(!vis[x][y]){
vis[x][y] = 1;
Q[r++] = Node(x, y);
}
}
}
}
}
return s;
}
void bfs(Node s){
memset(vis, 0, sizeof vis);
memset(Time, 0x3f, sizeof Time);
f = r = 0;
Q[r++] = s;
Time[s.x][s.y] = 0;
vis[s.x][s.y] = 1;
Node now;
int x, y;
while(f < r){
now = Q[f++];
for(int i = 0; i <4; i++){
x = now.x + d[i][0];
y = now.y + d[i][1];
if(ok(x, y) && !vis[x][y]){
if(maze[x][y] == '.'){
if(Time[now.x][now.y] + 1 < rock[x][y])
if(Time[now.x][now.y] + 1 < Time[x][y]){
Time[x][y] = Time[now.x][now.y] + 1;
Q[r++] = Node(x, y);
}
}else if(maze[x][y] == 'E'){
if(Time[now.x][now.y] + 1 <= rock[x][y]){
printf("Yes\n");
return ;
}
}
}
}
}
printf("No\n");
}
int main(){
//freopen("E:\\read.txt","r",stdin);
int T;
scanf("%d", &T);
while(T--){
bfs(Init());
}
return 0;
}
/*
100
3 4
!S..
....
...E
3 4
.S..
.!..
...E
3 4
.S..
...#
..#E
3 4
....
...S
..!E
1
1 3
!ES
*/