poj 1475 广搜
题意:推箱子 要求在推的次数最少的情况下,人移动次数最少
分析:pu[x1][y1][x2][y2]、mo[x1][y1][x2][y2]记录人在x1,y1 箱子在x2,y2时的最少推动次数和最少人移动次数。
const int maxn=1000000; int n,m,pp,p,ans,bestp,bestm; char c[25][25]; struct node{ int x1,y1,x2,y2,pus,mov; int pre; char op; }nd[maxn]; int mo[20][20][20][20],pu[20][20][20][20]; int tx[]={-1,1,0,0},ty[]={0,0,-1,1}; char dir[]={'n','s','w','e'}; char Dir[]={'N','S','W','E'}; queue<int> q; stack<int> s; bool can(int x,int y){ if(x>=0&&x<n&&y>=0&&y<m)return true; return false; } void shuchu(int i){ if(nd[i].pre!=-1){ shuchu(nd[i].pre); cout<<nd[i].op; } } void solve(){ while(!q.empty()){ int v=q.front(); q.pop(); for(int i=0;i<4;i++){ int xx1=nd[v].x1+tx[i], yy1=nd[v].y1+ty[i], xx2=nd[v].x2+tx[i],yy2=nd[v].y2+ty[i]; if(!can(xx1,yy1)||c[xx1][yy1]=='#')continue; if(xx1==nd[v].x2&&yy1==nd[v].y2) if(!can(xx2,yy2)) continue; int flag=0; if(s.empty())p=pp++; //标记p是怎么来的 移动步数大则不入队列 else {p=s.top();s.pop();flag=1;} nd[p].x1=xx1; nd[p].y1=yy1; nd[p].x2=nd[v].x2; nd[p].y2=nd[v].y2; nd[p].pre=v; nd[p].op=dir[i]; nd[p].mov=nd[v].mov+1; nd[p].pus=nd[v].pus; if(xx1==nd[v].x2&&yy1==nd[v].y2){ nd[p].x2=xx2; nd[p].y2=yy2; nd[p].op=Dir[i]; nd[p].pus++; } if(nd[p].pus<pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]||( nd[p].pus==pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]&& nd[p].mov<mo[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2])){ pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]=nd[p].pus; mo[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]=nd[p].mov; if(c[nd[p].x2][nd[p].y2]=='T'){ if(bestp>nd[p].pus||(bestp==nd[p].pus&&bestm>nd[p].mov)){ bestp=nd[p].pus; bestm=nd[p].mov; ans=p; } } else q.push(p); }else{ if(flag)s.push(p); else pp--; } } } } void read(){ pp=1; ans=-1; bestp=bestm=999999999; while(!q.empty()) q.pop(); while(!s.empty()) s.pop(); memset(mo,1,sizeof(mo)); memset(pu,1,sizeof(pu)); for(int i=0;i<n;i++){ cin>>c[i]; for(int j=0;j<m;j++){ if(c[i][j]=='S')nd[0].x1=i,nd[0].y1=j; else if(c[i][j]=='B')nd[0].x2=i,nd[0].y2=j; } } nd[0].pre=-1; nd[0].pus=nd[0].mov=0; q.push(0); } int main(){ int maze=1; while(cin>>n>>m){ if(n==0)break; read(); solve(); cout<<"Maze #"<<maze++<<endl; if(ans==-1) cout<<"Impossible."; else shuchu(ans); cout<<endl<<endl; } return 0; }