传送门
一个很简单的BFS,但注意f标记数组要开三维,来标记这个地方是嗑药到的还是没嗑药到的,因为可能不嗑药就可以到这个地方,你磕了药,然后无法到此地方,但是没有药无法在这个点移动,但你标记了,于是有药的无法拓展的这个点,导致无解(还是自己理解一下好)
#include <cstdio>
#include <iostream>
#include <cmath>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct tw{
int x,y;
int step;
int ful;
};
queue <tw> dl;
int dx[]={0,1,-1,0,0};
int dy[]={0,0,0,-1,1};
int n,m,d,r;
char map[999][999];
bool f[999][999][2];
int BFS()
{
f[1][1][1]=1;
dl.push((tw){1,1,0,1});
while(!dl.empty())
{
tw now=dl.front();
dl.pop();
if(now.x==n&&now.y==m)
return now.step;
for(int i=1;i<=4;i++)
{
int xx=now.x+dx[i],yy=now.y+dy[i];
if(xx<1||yy<1||xx>n||yy>m)
continue;
if(f[xx][yy][now.ful]||map[xx][yy]=='#')
continue;
f[xx][yy][now.ful]=1;
dl.push((tw){xx,yy,now.step+1,now.ful});
}
if(now.ful)
{
int xx=now.x+d,yy=now.y+r;
if(xx>=1&&yy>=1&&xx<=n&&yy<=m)
if(f[xx][yy][0]==0&&map[xx][yy]=='.')
{
f[xx][yy][0]=1;
dl.push((tw){xx,yy,now.step+1,0});
}
}
}
return -1;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&d,&r);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>map[i][j];
printf("%d",BFS());
return 0;
}