1475 Pushing Boxes
阿新 • • 發佈:2018-12-19
字元的讀入用的%c一開始沒有寫getchar(),(因為這個調了好久,難受啊T_T)
主要的思路:將盒子和人獨立開來思考,先寬搜盒子的前進路線,這時候需要判斷人能不能去推著盒子朝這個方向前進,即人能不能走到盒子前進的相反的位置上,盒子從(3,3)->(2,3),那人要能走到(4,3)的位置才行(才能推著盒子前進),人最短的路徑走到推箱子的位置這又是一個寬搜,第一個結構體為Status,記錄著盒子的座標,人的座標,和總的推盒子路徑(因為寬搜盒子的行走路徑是需要去寬搜人能不能到推的位置),第二個結構體為Person,記錄人的座標和人的行走路徑。
#include<iostream> #include<string> #include<queue> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; int dx[]={1,-1,0,0};//上下左右對應著s,n,e,w int dy[]={0,0,1,-1}; char Pp[]={'s','n','e','w'};//人移動 char Pb[]={'S','N','E','W'};//箱子移動 const int maxn=25; char Map[maxn][maxn]; bool vis_p[maxn][maxn],vis_b[maxn][maxn];//人和箱子獨立開來 int sx,sy,ex,ey,bx,by,r,c; struct Status{ int p_x,p_y; int b_x,b_y; string res; }p,q; struct Person{ int x,y; string ans; }P,Q; bool pd(int x,int y){ if(x>=0&&x<r&&y>=0&&y<c&&Map[x][y]!='#') return 1; else return 0; } bool Person_bfs(int s_x,int s_y,int e_x,int e_y){//寬搜人的行進 //返回可否從(s_x,s_y)->(e_x,e_y) memset(vis_p,0,sizeof(vis_p)); queue<Person> T; P.x=s_x,P.y=s_y; P.ans=""; vis_p[P.x][P.y]=1;//初始位置和現在箱子的位置標記為1 vis_p[p.b_x][p.b_y]=1; T.push(P); while (!T.empty()){ P = T.front(),T.pop(); if (P.x == e_x&&P.y == e_y) return 1; for (int i=0;i<4;i++){ int nx=P.x+dx[i]; int ny=P.y+dy[i]; if (pd(nx,ny)&&!vis_p[nx][ny]){ vis_p[nx][ny]=1; Q.ans=P.ans+Pp[i]; Q.x=nx; Q.y=ny; T.push(Q); } } } return 0; } bool Box_bfs(){//寬搜盒子 //返回可否走到終點 memset(vis_b,0,sizeof(vis_b)); queue<Status> T; p.b_x=bx,p.b_y=by; p.p_x=sx,p.p_y=sy; p.res=""; vis_b[bx][by]=1; T.push(p); while(!T.empty()){ p=T.front(),T.pop(); for(int i=0;i<4;++i){ int bbx=p.b_x+dx[i]; int bby=p.b_y+dy[i]; int ppx=p.b_x-dx[i];//因為人要從相反的方向推 int ppy=p.b_y-dy[i]; if(pd(bbx,bby)&&pd(ppx,ppy)&&!vis_b[bbx][bby]){ if(Person_bfs(p.p_x,p.p_y,ppx,ppy)){ //寬搜 人從原來的位置 到 推的位置 vis_b[bbx][bby]=1; q.b_x=bbx; q.b_y=bby; q.p_x=p.b_x; q.p_y=p.b_y; q.res=p.res+P.ans+Pb[i]; if(bbx==ex && bby==ey){ return 1; } T.push(q); } } } } return 0; } int main(){ int num=1; while(scanf("%d %d",&r,&c)!=EOF){ getchar();//吃掉回車 if(r==0&&c==0) break; for(int i=0;i<r;++i){ for(int j=0;j<c;++j){ scanf("%c",&Map[i][j]); if(Map[i][j]=='S') sx=i,sy=j; if(Map[i][j]=='T') ex=i,ey=j; if(Map[i][j]=='B') bx=i,by=j; } getchar();//吃掉回車 } cout<<"Maze #"<<num++<<endl; if(Box_bfs()){ cout<<q.res<<endl; } else cout<<"Impossible."<<endl; cout<<endl; } return 0; }
寫完之後有一個樣例一直調不出來(瘋狂掉頭髮~~~~
後來(。。。。)才發現我把 bool Person_bfs(int s_x,int s_y,int e_x,int e_y){裡的
vis_p[p.b_x][p.b_y]=1;寫成了vis_p[p.b_x][p.p_y]=1;
看了半天都沒看出來(喪~~~~~~
其實還因為poj不支援萬能標頭檔案,CE的好幾發(逃