當(dāng)前位置:
首頁 >
洛谷 P1126 机器人搬重物 (BFS)
發(fā)布時間:2023/10/11
123
老码农
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P1126 机器人搬重物 (BFS)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接:https://www.luogu.org/problemnew/show/P1126
吐槽:這題很陰險(xiǎn)
一開始沒把格子圖轉(zhuǎn)化成點(diǎn)圖:30分
轉(zhuǎn)化成點(diǎn)圖,發(fā)現(xiàn)樣例過不去,原來每步要判斷vis數(shù)組和step大小,尋找最優(yōu)解,一塊加了上去,以為能AX,結(jié)果邊界處理不對:50分
加了邊界后才AC。
(實(shí)際修改過程要坑爹的多orz 這么說吧,從20分到100分我全得過)
言歸正傳,搞一下這道題
廣搜題,思路很好想:用結(jié)構(gòu)體開個隊(duì)列,分別保存每步的坐標(biāo)、方向和步數(shù),用vis數(shù)組保存當(dāng)前格子上的最優(yōu)解,然后開一個ans數(shù)組,保存所有能跑到終點(diǎn)的步數(shù),搜完后,從ans中選一個最小的輸出。
這是大致的思路,具體實(shí)現(xiàn)還有很多細(xì)節(jié)和坑點(diǎn)。
- 輸入的格子圖要轉(zhuǎn)化成點(diǎn)圖,即
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;
}
}
- 要從點(diǎn)圖的周圍包上一層“1”,因?yàn)檫吔缫彩遣荒茏叩模ǘ嗝赐吹念I(lǐng)悟QAQ)
for(int i=1;i<=n;i++)
{
map[n][i]=1;
map[i][m]=1;
}
- 要把答案存起來,找一個最小的輸出(被我校dalao坑了 QAQ dalaoZZH:“廣搜先找到的一定是最優(yōu)解,所以把這句去了就行”)
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數(shù)組也要更新成最優(yōu)解
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;
}
- 方向也要判斷好
坑點(diǎn)差不多就這些了,接下來上代碼
#include<iostream>
#include<cstring>
using namespace std;
bool map[51][51]; //存地圖
int vis[51][51]; //存訪問過的最優(yōu)解
struct yyy{ //隊(duì)列
int x, //坐
y, //標(biāo)
dir, //方向
st; //步數(shù)
}q[5001];
int h=1,t; //隊(duì)頭、隊(duì)尾
int ans[5001]={-1},tot,minl=0x7fffff; //處理答案
int fx[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}}; //處理方向
int main()
{
//輸入+預(yù)處理地圖
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;
//預(yù)處理搜索
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數(shù)組初始化為一個很大的數(shù),"1"實(shí)際為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) //如果方向不一樣,則需轉(zhuǎn)彎,步數(shù)加一
{
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)) //如果向后轉(zhuǎn),需要轉(zhuǎn)兩次彎
step=q[h].st+2;
}
for(int j=1;j<=3;j++) //枚舉步數(shù)
{
int xx,yy;
xx=q[h].x+j*fx[i][0],yy=q[h].y+j*fx[i][1]; //xx、yy為目標(biāo)點(diǎn)坐標(biāo)
if(xx>n||xx<1||yy>m||yy<=0||map[xx][yy]) //如果越界或有障礙,直接退出循環(huán)
break;
if(vis[xx][yy]>step) //保存最優(yōu)解
{
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++) //尋找最優(yōu)答案
{
if(ans[i]<minl)
minl=ans[i];
}
//輸出
if(minl<0x7fffff)
cout<<minl;
else
cout<<-1;
return 0; //完美結(jié)束
}
最后打個廣告
我的洛谷博客
我的博客園博客
總結(jié)
以上是生活随笔為你收集整理的洛谷 P1126 机器人搬重物 (BFS)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 堆、栈、常量池等
- 下一篇: fedora23帮定键盘系统操作快捷键