luogu 1126 机器人搬重物

题目: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;  //完美结束 
}

猜你喜欢

转载自blog.csdn.net/qq_37073764/article/details/83116995