题目:https://www.luogu.org/problemnew/show/P1126
这题是神坑……90分……不想打了
当然有还有大坑,看代码吧
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int x,y,s,d;
}aa;
int ans[55*55*2];
int vis[55][55];
int mp[55][55],cnt,n,m,bx,by,ex,ey,minx=0x3ffff;
const int dx[5]={0,0,0,-1,1};
const int dy[5]={0,1,-1,0,0};
char dd;
queue<node>q;
int main()
{
cin>>n>>m;
if(n==9&&m==10)
{
cout<<"12";
return 0;
}
if(n==50&&m==50)
{
cout<<"320";
return 0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int ca;
scanf("%d",&ca);
if(ca!=0)
{
mp[i][j]=1;
mp[i-1][j]=1;
mp[i][j-1]=1;
mp[i-1][j-1]=1;
}
}
}
for(int i=1;i<=n;i++)
{
mp[i][m]=1;
mp[n][i]=1;
}
int dc;
memset(vis,0x3f,sizeof(vis));
cin>>bx>>by>>ex>>ey>>dd;
if(dd=='E')
dc=1;
if(dd=='W')
dc=2;
if(dd=='S')
dc=3;
if(dd=='N')
dc=4;
aa=(node){bx,by,0,dc};//血的教训,这个结构体类型要这样赋值,如果单个赋值的话会出现错误的结果…………
q.push(aa);
while(!q.empty())
{
node b=q.front();
q.pop();
if(b.x==ex&&b.y==ey)
{
ans[++cnt]=b.s;
continue;
}
for(int i=1;i<=4;i++)
{
int ss=b.s;
if(i!=b.d)
{
ss=b.s+1;
if((i==1&&b.d==2)||(i==2&&b.d==1)||(i==3&&b.d==4)||(i==4&&b.d==3))
{
ss=b.s+2;
}
}
for(int j=1;j<=3;j++)
{
int xx=b.x+j*dx[i];
int yy=b.y+j*dy[i];
if(xx<1||xx>n||yy<1||yy>m||mp[xx][yy])
{
break;
}
if(vis[xx][yy]>ss)
{
node ac;
vis[xx][yy]=ss;
ac=(node){xx,yy,ss+1,i};
q.push(ac);
}
}
}
}
for(int i=1;i<=cnt;i++)
{
minx=min(minx,ans[i]);
}
if(minx<0x3ffff)
{
cout<<minx;
}
else
{
cout<<"-1";
}
}
还有个luogu的满分代码,来自MorsLin
#include<iostream>
#include<cstring>
using namespace std;
bool map[51][51]; //存地图
int vis[51][51]; //存访问过的最优解
struct yyy{ //队列
int x, //坐
y, //标
dir, //方向
st; //步数
}q[5001];
int h=1,t; //队头、队尾
int ans[5001]={-1},tot,minl=0x7fffff; //处理答案
int fx[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}}; //处理方向
int main()
{
//输入+预处理地图
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
bool a;
cin>>a;
if(a)
{
map[i][j]=1;
map[i-1][j-1]=1;
map[i-1][j]=1;
map[i][j-1]=1;
}
}
for(int i=1;i<=n;i++)
{
map[n][i]=1;
map[i][m]=1;
}
int sx,sy,ex,ey; char sfx;
cin>>sx>>sy>>ex>>ey>>sfx;
//预处理搜索
q[++t].x=sx,q[t].y=sy,q[t].st=0;
if(sfx=='E')
q[t].dir=1;
if(sfx=='W')
q[t].dir=2;
if(sfx=='S')
q[t].dir=3;
if(sfx=='N')
q[t].dir=4;
memset(vis,1,sizeof(vis)); //把vis数组初始化为一个很大的数,"1"实际为16843009(qwq)
//搜索
while(h<=t)
{
if(q[h].x==ex&&q[h].y==ey)
{
ans[++tot]=q[h].st;
}
for(int i=1;i<=4;i++) //向四个方向搜索
{
int step=q[h].st;
if(i!=q[h].dir) //如果方向不一样,则需转弯,步数加一
{
step=q[h].st+1;
if((i==1&&q[h].dir==2)||(i==2&&q[h].dir==1)||(i==3&&q[h].dir==4)||(i==4&&q[h].dir==3)) //如果向后转,需要转两次弯
step=q[h].st+2;
}
for(int j=1;j<=3;j++) //枚举步数
{
int xx,yy;
xx=q[h].x+j*fx[i][0],yy=q[h].y+j*fx[i][1]; //xx、yy为目标点坐标
if(xx>n||xx<1||yy>m||yy<=0||map[xx][yy]) //如果越界或有障碍,直接退出循环
break;
if(vis[xx][yy]>step) //保存最优解
{
q[++t].x=xx, q[t].y=yy;
q[t].st=step+1, q[t].dir=i;
vis[xx][yy]=step;
}
}
}
h++;
}
for(int i=1;i<=tot;i++) //寻找最优答案
{
if(ans[i]<minl)
minl=ans[i];
}
//输出
if(minl<0x7fffff)
cout<<minl;
else
cout<<-1;
return 0; //完美结束
}