HDU 1254 推箱子

http://acm.hdu.edu.cn/showproblem.php?pid=1254

中文题;

这里要注意的有一点:求的是箱子要推动多少格才能到目标点,不要以人为基点求多少步,所以这里设计状态的时候要以箱子为主体,箱子每移动一格,这样状态的改变,而不是以为基点去搜状态了,这样设计状态的话,会wa。。。那么箱子怎么移动,人在箱子后面的一个格子里推,首先人在什么地方不是重要的,只要当前人所在的格子和箱子后面的格子是联通的,那么可以认为状态时一样,可以这样的转化。一个箱子一个人,四维hash判重。。hash[8][8][8][8]...

代码:

#include<iostream> #include<queue> using namespace std ; int dx[] = {0,-1,0,1} ; int dy[] = {-1,0,1,0} ; int n,m,map[8][8],hash[8][8][8][8],flag[8][8]; struct Node { int x,y; }; struct state { int bx,by,mx,my,st; }start,cur,next; bool logic(int x,int y) { if(x<0||x>=n||y<0||y>=m||map[x][y]==1) return false ; return true ; } queue<state>q; queue<Node>qq; int bfs1(int mmx,int mmy,int goalx,int goaly,int curbx,int curby) { while(!qq.empty()) qq.pop() ; Node begin,cur,next ; memset(flag,0,sizeof(flag)); flag[mmx][mmy] = 1 ; begin.x = mmx , begin.y = mmy ; map[start.bx][start.by] = 0 , map[curbx][curby] = 2 ; qq.push(begin); while(!qq.empty()) { cur = qq.front(); qq.pop(); if(cur.x==goalx&&cur.y==goaly) { map[start.bx][start.by] = 2 , map[curbx][curby] = 0 ; return true ; } for(int i=0;i<4;i++) { next.x = cur.x + dx[i] ; next.y = cur.y + dy[i] ; if(logic(next.x,next.y)&&map[next.x][next.y]!=2&&!flag[next.x][next.y]) { flag[next.x][next.y] = 1 ; qq.push(next); } } } map[start.bx][start.by] = 2 , map[curbx][curby] = 0 ; return false; } int bfs() { while(!q.empty()) q.pop(); q.push(start); while(!q.empty()) { cur = q.front() ; q.pop(); if(map[cur.bx][cur.by]==3) { return cur.st ; } for(int i=0;i<4;i++) { next = cur ; next.bx += dx[i] ; next.by += dy[i] ; next.st ++ ; int x = cur.bx - dx[i] ; int y = cur.by - dy[i] ; if(logic(next.bx,next.by)&&logic(x,y)&&bfs1(cur.mx,cur.my,x,y,cur.bx,cur.by)) { next.mx = x , next.my = y ; if(!hash[next.bx][next.by][next.mx][next.my]) { hash[next.bx][next.by][next.mx][next.my] = 1 ; q.push(next); } } } } return -1 ; } int main() { int cas ; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%d",&map[i][j]); if(map[i][j]==2) start.bx = i , start.by = j ; else if(map[i][j]==4) start.mx = i , start.my = j ; } } memset(hash,0,sizeof(hash)); hash[start.bx][start.by][start.mx][start.my] = 1 ; printf("%d/n",bfs()); } return 0 ; }   

你可能感兴趣的:(HDU 1254 推箱子)