思路就是从头尾两遍BFS
然后枚举每一个中间点(也就是在这里嗑药)
d1[][]表示从(1,1)到(i,j)的距离
d2[][]表示从(i,j)到(h,w)的距离
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int h,w,d,r;
bool vis[N][N];
int d1[N][N],d2[N][N];
char mp[N][N];
struct node{
int x,y,val;
};
int main(){
cin>>h>>w>>d>>r;
for(int i=1;i<=h;i++){
scanf("%s",mp[i]+1);
}
if(mp[1][1]=='#' || mp[h][w]=='#'){
cout<<-1<<endl;
return 0;
}
memset(d1,-1,sizeof d1);
queue<node>q;
q.push((node){1,1,0});
d1[1][1]=0;
while(!q.empty()){
node tmp=q.front();
q.pop();//弹出
for(int i=0;i<4;i++){
int fx=tmp.x+dx[i];
int fy=tmp.y+dy[i];
if(fx>=1 && fx<=h && fy>=1 && fy<=w && d1[fx][fy]==-1 && mp[fx][fy]=='.'){
d1[fx][fy]=tmp.val+1;
q.push((node){fx,fy,d1[fx][fy]});
}
}
}
memset(d2,-1,sizeof d2);
queue<node>p;
p.push((node){h,w,0});
d2[h][w]=0;
while(!p.empty()){
node tmp=p.front();
p.pop();
for(int i=0;i<4;i++){
int fx=tmp.x+dx[i];
int fy=tmp.y+dy[i];
if(fx>=1 && fx<=h && fy>=1 && fy<=w && d2[fx][fy]==-1 && mp[fx][fy]=='.'){
d2[fx][fy]=tmp.val+1;
p.push((node){fx,fy,d2[fx][fy]});
}
}
}
int ans=INT_MAX;bool flag=0;
for(int i=1;i<=h;i++){
if((i+d)<=0 || (i+d)>h)continue;
for(int j=1;j<=w;j++){
if((j+r)<=0 || (j+r)>w)continue;
if(d1[i][j]==-1 || d2[i+d][j+r]==-1)continue;
ans=min(ans,d1[i][j]+1+d2[i+d][j+r]);
if((d1[i][j]!=-1 && d2[i+d][j+r]!=-1)){
flag=1;
}
}
}
if(!flag)cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}