题目链接:
http://codeforces.com/problemset/problem/585/B
题目大意:
有个人从左往右走路,有三种不同走法:1、往右走一步。2、往右走一步再往上走一步。3、往右走一步再往下走一步。
走的过程中会有火车跑过来,每次火车都会走两步。规定是人先走一次,然后所有火车再走一次。
问能不能不被火车撞到并且到达最右边。
思路:
可以用bfs。
因为最长为100,所以只要预处理出这100秒的图,即在这一秒时哪些地方不能走。然后进行宽搜。
注意:如果往右走一步已经不能成功,那么剩下两种方法就一定行不通了。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
int n,k,s1,s2;
bool vis[105][105][105],v[105][105];
char mps[105][105];
struct node{
int x,y,t;
};
int dir[5][2]={0,1,1,1,-1,1};
queue<node>qu;
bool bfs(int x,int y,int t)
{
node p,q;
p.x=x;
p.y=y;
p.t=t;
qu.push(p);
while(!qu.empty())
{
p=qu.front();
qu.pop();
if(p.y==n)return 1;
for(int i=0;i<3;i++)
{
q=p;
q.x=p.x+dir[i][0];
q.y=p.y+dir[i][1];
q.t=p.t;
if(q.x<=0||q.x>3||q.y<=0||q.y>n)continue;
if(vis[q.x][q.y][q.t]&&i==0)break;
if(!v[q.x][q.y]&&!vis[q.x][q.y][q.t+1]&&!vis[q.x][q.y][q.t]){ //如果下一步走的地方有车就不行。
v[q.x][q.y]=1;
q.t = p.t + 1;
qu.push(q);
}
}
}
return 0;
}
int main()
{
int t,T,i,j;
scanf("%d",&T);
while(T--)
{
while(!qu.empty())
qu.pop();
memset(vis,0,sizeof(vis));
memset(v,0,sizeof(v));
memset(mps,0,sizeof(mps));
scanf("%d%d",&n,&k);
for(i=1;i<=3;i++)
for(j=1;j<=n;j++)
{
cin>>mps[i][j];
if(mps[i][j]=='.')vis[i][j][0]=0;
else vis[i][j][0]=1;
if(mps[i][j]=='s'){
s1=i;
s2=j;
}
}
for(t=1;t<=100;t++)
{
for(i=1;i<=3;i++)
for(j=1;j<=n;j++)
{
if(vis[i][j][t-1]==1)vis[i][j-2][t]=1;
}
}
//预处理出图。
if(bfs(s1,s2,0))printf("YES\n");
else printf("NO\n");
}
return 0;
}