我的思路是将每个格子的坐标转化为它的左上角,然后分别给边界扩一,即就是以n+1,m+1为边长建图,最左上的起始为(1,1)。 用1,2,3,4表示东南西北(右下左上),用一个数组(代码中是dd[])来记录方向记录数的差所意义的花费(就是不转就花费1,转90度就花费2...)。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
const int dx[]={0,0,1,0,-1},dy[]={0,1,0,-1,0},dd[]={1,2,3,2}; //东南西北
int n,m,stx,sty,edx,edy;
int vis[maxn][maxn],mp[maxn][maxn];
string msk;
struct node {int x,y,t;};
queue <node> q;
inline void bfs()
{
while(!q.empty())
{
node nw=q.front();q.pop();
for(int i=1;i<=4;++i)
{
for(int j=1;j<=3;++j)
{
int nx=nw.x+dx[i]*j,ny=nw.y+dy[i]*j;
if(nx<1||nx>n+1||ny<1||ny>m+1) continue;
if(vis[nx][ny]) continue;
if(mp[nx][ny]==-1) break;
vis[nx][ny]=1;
mp[nx][ny]=mp[nw.x][nw.y]+dd[abs(nw.t-i)];
q.push((node){nx,ny,i});
}
}
}
}
signed main(void)
{
std::ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
int x;
cin>>x;
if(x) mp[i][j]=mp[i+1][j]=mp[i][j+1]=mp[i+1][j+1]=-1;
}
cin>>stx>>sty>>edx>>edy>>msk;
//if(stx==edx&&sty==edy) cout<<0;
++stx,++sty,++edx,++edy;
if(msk=="E") q.push((node){stx,sty,1});
else if(msk=="S") q.push((node){stx,sty,2});
else if(msk=="W") q.push((node){stx,sty,3});
else if(msk=="N") q.push((node){stx,sty,4});
vis[stx][sty]=1;
bfs();
if(!vis[edx][edy]) cout<<"-1";
else cout<<mp[edx][edy];
return 0;
}