日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

洛谷 P1126 机器人搬重物 (BFS)

發布時間:2023/10/11 综合教程 107 老码农
生活随笔 收集整理的這篇文章主要介紹了 洛谷 P1126 机器人搬重物 (BFS) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:https://www.luogu.org/problemnew/show/P1126

吐槽:這題很陰險

  • 一開始沒把格子圖轉化成點圖:30分

  • 轉化成點圖,發現樣例過不去,原來每步要判斷vis數組和step大小,尋找最優解,一塊加了上去,以為能AX,結果邊界處理不對:50分

  • 加了邊界后才AC。

(實際修改過程要坑爹的多orz 這么說吧,從20分到100分我全得過)

言歸正傳,搞一下這道題

廣搜題,思路很好想:用結構體開個隊列,分別保存每步的坐標、方向和步數,用vis數組保存當前格子上的最優解,然后開一個ans數組,保存所有能跑到終點的步數,搜完后,從ans中選一個最小的輸出。

這是大致的思路,具體實現還有很多細節和坑點。

  1. 輸入的格子圖要轉化成點圖,即
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;
            }
        }
  1. 要從點圖的周圍包上一層“1”,因為邊界也是不能走的(多么痛的領悟QAQ)
for(int i=1;i<=n;i++)
{
        map[n][i]=1;
        map[i][m]=1;
}
  1. 要把答案存起來,找一個最小的輸出(被我校dalao坑了 QAQ dalaoZZH:“廣搜先找到的一定是最優解,所以把這句去了就行”)
if(q[h].x==ex&&q[h].y==ey)
 {
       ans[++tot]=q[h].st;
 }

 for(int i=1;i<=tot;i++)
    {
        if(ans[i]<minl)
           minl=ans[i];
    }
  1. vis數組也要更新成最優解
  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;
  }
  1. 方向也要判斷好

坑點差不多就這些了,接下來上代碼

#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;  //完美結束
}

最后打個廣告

我的洛谷博客

我的博客園博客

總結

以上是生活随笔為你收集整理的洛谷 P1126 机器人搬重物 (BFS)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。