Roll The Cube
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 484 Accepted Submission(s): 172
Problem Description
This is a simple game.The goal of the game is to roll two balls to two holes each.
‘B‘ -- ball
‘H‘ -- hole
‘.‘ -- land
‘*‘ -- wall
Remember when a ball rolls into a hole, they(the ball and the hole) disappeared, that is , ‘H‘ + ‘B‘ = ‘.‘.
Now you are controlling two balls at the same time.Up, down , left , right --- once one of these keys is pressed, balls exist roll to that direction, for example , you pressed up , two balls both roll up.
A ball will stay where it is if its next point is a wall, and balls can‘t be overlap.
Your code should give the minimun times you press the keys to achieve the goal.
Input
First there‘s an integer T(T<=100) indicating the case number.
Then T blocks , each block has two integers n , m (n , m <= 22) indicating size of the map.
Then n lines each with m characters.
There‘ll always be two balls(B) and two holes(H) in a map.
The boundary of the map is always walls(*).
Output
The minimum times you press to achieve the goal.
Tell me "Sorry , sir , my poor program fails to get an answer." if you can never achieve the goal.
Sample Input
4 6 3 *** *B* *B* *H* *H* *** 4 4 **** *BB* *HH* **** 4 4 **** *BH* *HB* **** 5 6 ****** *.BB** *.H*H* *..*.* ******
Sample Output
3 1 2 Sorry , sir , my poor program fails to get an answer.
Author
MadFroG
Source
HDOJ Monthly Contest – 2010.02.06
#include<stdio.h> #include<iostream> #include<queue> #include<string.h> using namespace std; struct node { int x[2],y[2],b,h; }; char tmap[25][25]; int n,m,dir[4][2]={0,1,0,-1,1,0,-1,0},hx[2],hy[2]; int isOk(int x,int y) { if(x<0||x>=n||y<0||y>=m||tmap[x][y]=='*') return 0; return 1; } int bfs(int bx[],int by[]) { int time=0,flag=0; node p,tp; queue<node>q[2]; //vist1用于两个球相对位置走过的情况,vist2用于剩于一个球与剩于一个洞相对位置走过的情况 bool vist1[25][25][25][25]={0},vist2[25][25][25][25]={0}; vist1[bx[0]][by[0]][bx[1]][by[1]]=1; vist1[bx[1]][by[1]][bx[0]][by[0]]=1; p.x[0]=bx[0]; p.y[0]=by[0]; p.x[1]=bx[1]; p.y[1]=by[1]; p.b=2; p.h=2; q[0].push(p); while(!q[flag].empty()) { time++; while(!q[flag].empty()) { p=q[flag].front(); q[flag].pop(); for(int e=0;e<4;e++) { tp=p; tp.x[0]+=dir[e][0]; tp.y[0]+=dir[e][1]; tp.x[1]+=dir[e][0]; tp.y[1]+=dir[e][1]; if(tp.b==2) { if(!isOk(tp.x[0],tp.y[0])) //球0原地不动 tp.x[0]=p.x[0],tp.y[0]=p.y[0]; if(!isOk(tp.x[1],tp.y[1])) //球1原地不动 tp.x[1]=p.x[1],tp.y[1]=p.y[1]; if(tp.x[0]==tp.x[1]&&tp.y[0]==tp.y[1]) //两球位置一样 continue; if(vist1[tp.x[0]][tp.y[0]][tp.x[1]][tp.y[1]])//两球的相对位置存在过 continue; if(tmap[tp.x[0]][tp.y[0]]=='0'||tmap[tp.x[0]][tp.y[0]]=='1')//球0进洞 { tp.b=1; //还剩球1 if(tmap[tp.x[0]][tp.y[0]]=='0') tp.h=1; //还剩洞1 else tp.h=0; //还剩洞0 } if(tmap[tp.x[1]][tp.y[1]]=='0'||tmap[tp.x[1]][tp.y[1]]=='1')//球1进洞 { if(tp.b==1)//两球一起进洞 return time; tp.b=0; //还剩球0 if(tmap[tp.x[1]][tp.y[1]]=='0') tp.h=1; else tp.h=0; } if(tp.b!=2) //只进了一个球 { int b,h; b=tp.b; h=tp.h; vist2[tp.x[b]][tp.y[b]][hx[h]][hy[h]]=1; } vist1[tp.x[0]][tp.y[0]][tp.x[1]][tp.y[1]]=1; vist1[tp.x[1]][tp.y[1]][tp.x[0]][tp.y[0]]=1; } else { int x,y,b,h; b=tp.b; h=tp.h; x=tp.x[b]; y=tp.y[b]; if(!isOk(x,y)||vist2[x][y][hx[h]][hy[h]]) continue; if(x==hx[h]&&y==hy[h]) //剩下的球位进入剩下的洞 return time; vist2[x][y][hx[h]][hy[h]]=1; } q[flag^1].push(tp); } } flag^=1; } return 0; } int main() { int T,bk,hk,x[2],y[2]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); bk=hk=0; for(int i=0;i<n;i++) { scanf("%s",tmap[i]); for(int j=0;j<m;j++) if(tmap[i][j]=='B') { x[bk]=i; y[bk]=j; tmap[i][j]='.'; bk++; } else if(tmap[i][j]=='H') { hx[hk]=i; hy[hk]=j; tmap[i][j]=hk+'0'; hk++; } } int ans=bfs(x,y); if(ans) printf("%d\n",ans); else printf("Sorry , sir , my poor program fails to get an answer.\n"); } }