洛谷 P1126 机器人搬重物 (BFS)
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P1126 机器人搬重物 (BFS)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:https://www.luogu.org/problemnew/show/P1126
吐槽:這題很陰險
一開始沒把格子圖轉化成點圖:30分
轉化成點圖,發現樣例過不去,原來每步要判斷vis數組和step大小,尋找最優解,一塊加了上去,以為能AX,結果邊界處理不對:50分
加了邊界后才AC。
(實際修改過程要坑爹的多orz 這么說吧,從20分到100分我全得過)
言歸正傳,搞一下這道題
廣搜題,思路很好想:用結構體開個隊列,分別保存每步的坐標、方向和步數,用vis數組保存當前格子上的最優解,然后開一個ans數組,保存所有能跑到終點的步數,搜完后,從ans中選一個最小的輸出。
這是大致的思路,具體實現還有很多細節和坑點。
- 輸入的格子圖要轉化成點圖,即
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”,因為邊界也是不能走的(多么痛的領悟QAQ)
for(int i=1;i<=n;i++)
{
map[n][i]=1;
map[i][m]=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];
}
- 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;
}
- 方向也要判斷好
坑點差不多就這些了,接下來上代碼
#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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 堆、栈、常量池等
- 下一篇: fedora23帮定键盘系统操作快捷键