CF793B Igor and his way to work 题解
题意
有一个 \(n\times m\) 的矩阵,有 \(4\) 种道路,.
是可行的道路, *
是不可行的道路, S
是起点, T
是终点,且只能转 \(2\) 次弯,问是否能从起点走到终点。
分析
在 bfs 的时候记录一下当前转弯的次数,如果下一步走的方向和上一步走的方向不同,就加上这次转弯的次数。
代码
#include <bits/stdc++.h>
#define elif else if
using namespace std;
const int MAXN=1e3+7;
char a[MAXN][MAXN];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int vis[1005][1005][4][2];
int n,m;
struct node
{
int x,y,z,turns;
};
bool bfs(node u)
{
queue<node>q;
for(register int i=0;i<4;i++) //4个方向
{
node v=u;
v.x+=dx[i];
v.y+=dy[i];
if(v.x>=1&&v.x<=n&&v.y>=1&&v.y<=m&&a[v.x][v.y]!='*') //能走
{
v.z=i;
v.turns=2;
vis[v.x][v.y][i][2]=1;
q.push(v);
}
}
while(!q.empty())
{
node u=q.front();
q.pop();
if(a[u.x][u.y]=='T') return true; //走到终点了
for(register int i=0;i<4;i++)
{
node v=u;
v.x+=dx[i];
v.y+=dy[i];
if(v.x>=1&&v.x<=n&&v.y>=1&&v.y<=m&&a[v.x][v.y]!='*') //下一步能走
{
if(v.z==i) //方向不变
{
if(!vis[v.x][v.y][i][v.turns]) //之前没有相同方向走过
{
q.push(v);
vis[v.x][v.y][i][v.turns]=true;
}
}
elif(v.turns>0)
{
if(!vis[v.x][v.y][i][v.turns-1])
{
v.turns--;
v.z=i;
vis[v.x][v.y][i][v.turns]=true;
q.push(v);
}
}
}
}
}
return 0;
}
int main()
{
cin>>n>>m;
node start;
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='S') //记录起点
{
start.x=i;
start.y=j;
}
}
}
if(bfs(start)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}