hdu 1254 推箱子
用BFS让箱子走一遍即可。
其中判断箱子能否往前走,除了看它前面是否为墙,还要判断人能不能到它后面的方格。
还有标记状态,箱子和人有一个位置不同,便是不同的状态。我用的哈希判重,其实开个四维数组也行,毕竟数据范围不大。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define FOR(i,s,t) for(int i = (s) ; i <= (t) ; ++i ) #define lchild o<<1 #define rchild o<<1|1 typedef long long ll; typedef unsigned long long ull; using namespace std; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=10007; int dir[4][2]={0,-1,0,1,-1,0,1,0}; int t,m,n,ans; int mp[10][10]; struct node { int bx,by,px,py;//箱子的坐标和人的坐标 int step; inline int operator==(const node & a) { if( bx!=a.bx )return false; if( by!=a.by )return false; if( px!=a.px )return false; if( py!=a.py )return false; return true; } bool friend operator<(node a,node b) { return a.step>b.step; } }; node start; vector <node> v[maxn]; int myhash(node a){ return (a.bx * 11 + a.by*111 + a.px*1111 + a.py*11111 ) % maxn; } bool ok(int x,int y){ if( x<0 || x>=m )return false; if( y<0 || y>=n )return false; if( mp[x][y]==1 )return false; return true; } bool visit(node a){ int ha = myhash(a); int num = v[ha].size(); for(int i=0 ; i<num ; ++i){ if( v[ha][i] == a ){ //printf("has vised this state.\n"); return true; } } v[ha].push_back(a); return false; } bool cango(node a,int sx,int sy){ //printf("box : %d,%d ; if can go to %d,%d \n",a.bx,a.by,sx,sy ); //bfs判断人能否到达mp[sx][sy] node now=a,next; bool vis[10][10]; memset(vis,0,sizeof vis); vis[now.px][now.py]=1; queue<node>q2; q2.push(now); while(!q2.empty()){ now=q2.front(); q2.pop(); //printf("now peo:: %d,%d\n",now.px,now.py ); if(now.px==sx && now.py==sy){ return true; } for(int i=0;i<4;++i){ int nx = now.px+dir[i][0]; int ny = now.py+dir[i][1]; if( !ok(nx,ny) )continue; if( vis[nx][ny])continue; if( nx == now.bx && ny == now.by )continue; vis[nx][ny]=1; next.bx=now.bx; next.by=now.by; next.px=nx; next.py=ny; next.step=now.step+1; //printf(" next peo:: %d,%d\n",next.px,next.py ); q2.push(next); } } return false; } int bfs(){ node now = start,next ; priority_queue <node> q; q.push(now); visit(now); while( !q.empty() ){ now=q.top(); q.pop(); //printf("now box:: %d,%d\n",now.bx,now.by ); if( mp[now.bx][now.by]==3 ){ return now.step; } for(int i=0;i<4;++i){ int nx = now.bx + dir[i][0]; int ny = now.by + dir[i][1]; if( !ok(nx,ny) )continue; int lx = now.bx - dir[i][0]; int ly = now.by - dir[i][1]; if( !ok(lx,ly) )continue; if( cango(now,lx,ly) ){ next.bx=nx; next.by=ny; next.px=now.bx; next.py=now.by; next.step=now.step+1; if( !visit(next) ) q.push(next); } } } return -1; } int main() { //freopen("in.txt","r",stdin); Ri(t); while(t--){ for(int i=0;i<maxn;++i)v[i].clear(); Ri(m);Ri(n); for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ Ri( mp[i][j] ); if(mp[i][j]==2){ start.bx=i; start.by=j; }else if(mp[i][j]==4){ start.px=i; start.py=j; start.step=0; } //printf("%d ",mp[i][j] ); } //printf("\n"); } ans=bfs(); printf("%d\n",ans ); } return 0; }