题目地址:https://www.luogu.org/problem/P1126
看着机房孙哥再做这个题,我也尝试一波,没想到卡了这么长时间,总结一下,这题细节超多,一开始写了个有返回值的bfs,wa,还得注意转向的问题,走一步,两步,三步都是一秒,还有对初始坐标点的处理。。。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=50+10;
struct Node
{
int x;
int y;
int time;
char dir;
};
int n,m,sx,sy,fx,fy,a[maxn][maxn],dis[4][2]={0,1,1,0,0,-1,-1,0};
int vis[maxn][maxn];
char c,s[4]={'S','W','N','E'};
queue<Node> q;
bool judge(int x,int y)
{
bool error=false;
if(a[x][y]==0&&x>=1&&y>=1&&x<n&&y<m&&a[x-1][y-1]==0&&a[x-1][y]==0&&a[x][y-1]==0)
{
error=false;
}
else error=true;
if(error==true)
return false;
else
return true;
}
void bfs()
{
while(!q.empty())
{
Node now=q.front();
q.pop();
char to=now.dir;
int num;
for(int i=0;i<4;i++)
{
if(s[i]==to)
num=i;
}
for(int i=0;i<4;i++)
{
int k=fabs(i-num),tx=now.x,ty=now.y,walk_2=0,walk_3=0;
if(k==3) k=1;
else if(k==2) k=2;
else if(k==1) k=1;
else if(k==0) k=0;
if(i==0)tx++;
if(i==1)ty--;
if(i==2)tx--;
if(i==3)ty++;
if(judge(tx,ty))
{
walk_2=1;
if(vis[tx][ty]>now.time+k+1)
{
q.push({tx,ty,now.time+k+1,s[i]});
vis[tx][ty]=now.time+k+1;
}
}
if(walk_2==1)
{
if(i==0)tx++;
if(i==1)ty--;
if(i==2)tx--;
if(i==3)ty++;
if(judge(tx,ty))
{
walk_3=1;
if(vis[tx][ty]>now.time+k+1)
{
q.push({tx,ty,now.time+k+1,s[i]});
vis[tx][ty]=now.time+k+1;
}
}
}
if(walk_3==1)
{
if(i==0)tx++;
if(i==1)ty--;
if(i==2)tx--;
if(i==3)ty++;
if(judge(tx,ty))
{
if(vis[tx][ty]>now.time+k+1)
{
q.push({tx,ty,now.time+k+1,s[i]});
vis[tx][ty]=now.time+k+1;
}
}
}
}
}
}
int main()
{
memset(vis,inf,sizeof vis);
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
scanf("%d %d %d %d %c",&sx,&sy,&fx,&fy,&c);
q.push({sx,sy,0,c});
vis[sx][sy]=0;
bfs();
if(vis[fx][fy]==inf)
printf("-1\n");
else
printf("%d",vis[fx][fy]);
return 0;
}