Accept: 123 Submit: 678
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
有多组测试数据。
每组测试数据第一行是一个整数T,代表接下去的例子数。(0<=T<=10)
接下来是T组例子。
每组例子第一行是两个整数N和M。代表迷宫的大小有N行M列(0<=N,M<=1000)。
接下来是一个N*M的迷宫描述。
S代表小明的所在地。
E代表出口,出口只有一个。
.代表可以行走的地方。
!代表岩浆的产生地。(这样的地方会有多个,其个数小于等于10000)
#代表迷宫中的墙,其不仅能阻挡小明前进也能阻挡岩浆的蔓延。
小明携带者宝藏每秒只能向周围移动一格,小明不能碰触到岩浆(小明不能和岩浆处在同一格)。
岩浆每秒会向四周不是墙的地方蔓延一格。
小明先移动完成后,岩浆才会蔓延到对应的格子里。
小明能移动到出口,则小明顺利逃脱。
Output
Sample Input
Source
福州大学第十二届程序设计竞赛题目链接 :http://acm.fzu.edu.cn/problem.php?pid=2196
解题思路: 题目出的很好,尝试用DFS写,结果T了。第一个BFS用来得到岩浆蔓延到每个格子的时间,第二个BFS用来搜索逃跑路径,通过判断到达格子的时间和岩浆抵达的时间就很容易判断这一步是否能走。
wa点:1.标记岩浆抵达的时间和标记岩浆永远不能抵达要区别开。比如标记岩浆源处(最开始有岩浆的地方)标记时间为1,这样时间为0的格子代表岩浆永远不会抵达。
2.注意如果小明和岩浆同时到达E时,判断是可以逃生的。
代码如下:
#include <cstdio>
#include <cstring>
#include <queue>
#define inf 1e9
using namespace std;
const int maxn=1005;
int n,m,cnt;
bool p;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int eg[maxn][maxn];
char s[maxn][maxn]; //地图
int st[maxn][maxn],vis[maxn][maxn]; //st表示岩浆抵达的时间,vis标记是否访问过
struct node //每一个格子的坐标和时间
{
int x,y,tm; //第一个BFS的时间是指岩浆抵达的时间,第二个BFS的时间是小明抵达的时间
};
void bfs()
{
queue<node>q;
node nd;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(s[i][j]=='!')
{
nd.x=i;
nd.y=j;
nd.tm=0;
st[i][j]=1; //岩浆蔓延的起始时间为1
vis[i][j]=1;
q.push(nd);
}
}
while(!q.empty())
{
nd=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx=nd.x+dx[i];
int ny=nd.y+dy[i];
if(nx<0||nx>=n||ny<0||ny>=m||s[nx][ny]=='#'||vis[nx][ny])
continue;
node nn;
nn.x=nx;
nn.y=ny;
nn.tm=nd.tm+1;
st[nx][ny]=nn.tm;
vis[nx][ny]=1;
q.push(nn);
}
}
}
void bfs2(int sx,int sy)
{
node nd;
queue<node>q;
nd.x=sx;
nd.y=sy;
nd.tm=1;
q.push(nd);
while(!q.empty())
{
nd=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx=nd.x+dx[i];
int ny=nd.y+dy[i];
if(nx<0||nx>=n||ny<0||ny>=m||s[nx][ny]=='#'||vis[nx][ny])
continue;
if(s[nx][ny]=='E'&&st[nx][ny]>=nd.tm)//若小明和岩浆同时抵达,小明可以逃生
{
p=true;
return;
}
if(st[nx][ny]&&st[nx][ny]<=nd.tm) //岩浆先抵达了格子,不能通行
continue;
node nn;
nn.x=nx;
nn.y=ny;
nn.tm=nd.tm+1;
vis[nx][ny]=1;
q.push(nn);
}
}
}
int main(void)
{
int t;
scanf("%d",&t);
while(t--)
{
int sx,sy;
p=0,cnt=0;
memset(st,0,sizeof(st));
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<m;j++)
{
if(s[i][j]=='S')
{
sx=i;
sy=j;
}
}
}
bfs();
memset(vis,0,sizeof(vis));
bfs2(sx,sy);
if(p)
printf("Yes\n");
else
printf("No\n");
}
}