ps:其实这是一个游戏 贴个链接 可以进去玩玩之后再做这题 很有感觉的 (不要玩上瘾呦)
http://user.qzone.qq.com/1019256391?ptlang=2052#!app=2&via=QZ.HashRefresh&pos=1309244406
思路:只要把箱子的状态表示出来了就好办了 模拟箱子滚动和判重都不是问题了
代码:
// 这题被自己坑了 异想天开的用bool表示 0 1 2 // 本来可以避免的错误 自己挖个坑往坑里跳 我晕 ╮(╯▽╰)╭ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #define maxn 510 using namespace std; int n,m,ans,cnt,xxc; int sx[2],sy[2],ex,ey; char s[maxn]; int mp[maxn][maxn]; bool vis[4][maxn][maxn]; // 判重 箱子状态+左上角箱子所在坐标 struct Node { int x[2],y[2]; int step,type; }cur,now; queue<Node>q; bool isok() // 对cur进行判断即可 { int i,j,t,xx[2],yy[2]; t=cur.type; xx[0]=cur.x[0]; xx[1]=cur.x[1]; yy[0]=cur.y[0]; yy[1]=cur.y[1]; // printf("t:%d xx[0]:%d yy[0]:%d\n",t,xx[0],yy[0]); if(vis[t][xx[0]][yy[0]]) return false ; if(t==1) { if(mp[xx[0]][yy[0]]==0||mp[xx[0]][yy[0]]==2) return false ; // 状态为一时需判断地图是否为 easily broken cell } else { for(i=0;i<2;i++) { if(mp[xx[i]][yy[i]]==0) return false ; } } return true ; } bool bfs() { int i,j; int nx[2],ny[2],nstep,ntype; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); if(xxc) { if(sx[1]-sx[0]==1) cur.type=3; else cur.type=2; cur.x[0]=sx[0]; cur.x[1]=sx[1]; cur.y[0]=sy[0]; cur.y[1]=sy[1]; } else { cur.type=1; cur.x[0]=sx[0]; cur.y[0]=sy[0]; } cur.step=0; vis[cur.type][sx[0]][sy[0]]=1; q.push(cur); while(!q.empty()) { now=q.front(); q.pop(); ntype=now.type; nstep=now.step; nx[0]=now.x[0]; nx[1]=now.x[1]; ny[0]=now.y[0]; ny[1]=now.y[1]; if(ntype==1&&nx[0]==ex&&ny[0]==ey) { ans=nstep; return true ; } cur.step=nstep+1; if(ntype==1) { cur.type=2; cur.y[0]=ny[0]-2; cur.y[1]=ny[0]-1; cur.x[0]=cur.x[1]=nx[0]; if(isok()) // 左 { vis[2][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.y[0]=ny[0]+1; cur.y[1]=ny[0]+2; if(isok()) // 右 { vis[2][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.type=3; cur.x[0]=nx[0]-2; cur.x[1]=nx[0]-1; cur.y[0]=cur.y[1]=ny[0]; if(isok()) // 上 { vis[3][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.x[0]=nx[0]+1; cur.x[1]=nx[0]+2; if(isok()) // 下 { vis[3][cur.x[0]][cur.y[0]]=1; q.push(cur); } } else if(ntype==2) { cur.type=2; cur.x[0]=cur.x[1]=nx[0]-1; cur.y[0]=ny[0]; cur.y[1]=ny[1]; if(isok()) // 上 { vis[2][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.x[0]=cur.x[1]=nx[0]+1; if(isok()) // 下 { vis[2][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.type=1; cur.x[0]=nx[0]; cur.y[0]=ny[0]-1; if(isok()) // 左 { vis[1][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.y[0]=ny[0]+2; if(isok()) // 右 { vis[1][cur.x[0]][cur.y[0]]=1; q.push(cur); } } else { cur.type=1; cur.x[0]=nx[0]-1; cur.y[0]=ny[0]; if(isok()) // 上 { vis[1][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.x[0]=nx[0]+2; if(isok()) // 下 { vis[1][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.type=3; cur.x[0]=nx[0]; cur.x[1]=nx[1]; cur.y[0]=cur.y[1]=ny[0]-1; if(isok()) // 左 { vis[3][cur.x[0]][cur.y[0]]=1; q.push(cur); } cur.y[0]=cur.y[1]=ny[0]+1; if(isok()) // 右 { vis[3][cur.x[0]][cur.y[0]]=1; q.push(cur); } } } return false ; } int main() { int i,j; while(scanf("%d%d",&n,&m),n||m) { memset(mp,0,sizeof(mp)); xxc=-1; for(i=1;i<=n;i++) { scanf("%s",s); for(j=1;j<=m;j++) { if(s[j-1]=='.') { mp[i][j]=1; } else if(s[j-1]=='O') { mp[i][j]=1; ex=i; ey=j; } else if(s[j-1]=='E') { mp[i][j]=2; } else if(s[j-1]=='X') { xxc++; mp[i][j]=1; sx[xxc]=i; sy[xxc]=j; } } } if(bfs()) printf("%d\n",ans); else printf("Impossible\n"); } return 0; }