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.
'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(*).
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.
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 2Sorry , sir , my poor program fails to get an answer.
题意:给出两个球,两个洞,两个球每次同方向的滚动,'.'是空地,可以走,'*'是墙,不能走,球滚后之后球的位置变成‘.’,进洞后洞的位置也变成‘.’,则说明每个洞只能进一个球,每次滚动需要一分钟,最少什么时间两球都能进洞
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; int n,m; char a[25][25]; int aa[25][25]; int a1[2],b1[2],a2[2],b2[2]; int t[4][2]= {0,1,1,0,0,-1,-1,0}; //定义四个方向 int v[25][25][25][25]; int flag; struct p { int x[2]; //x[],y[]数组记录球的位置 int y[2]; int xx[2]; //记录当前位置呢个球进入洞 int hole[2]; //标记已有球进入的洞,另一个球则不能进 int step; }; void bfs() { p tmp,now; queue<p>Q; for(int i=0; i<2; i++) { now.x[i]=a1[i]; now.y[i]=b1[i]; now.xx[i]=now.hole[i]=0; } v[a1[0]][b1[0]][a1[1]][b1[1]]=1; now.step=0; Q.push(now); //将两球的初始状态情况入队 while(!Q.empty()) { now=Q.front(); Q.pop(); for(int i=0; i<4; i++) { tmp=now; for(int j=0; j<2; j++) { if(tmp.xx[j]==1) continue; tmp.x[j]+=t[i][0]; tmp.y[j]+=t[i][1]; if(a[tmp.x[j]][tmp.y[j]]=='*') //不能走时就停留在原地 { tmp.x[j]-=t[i][0]; tmp.y[j]-=t[i][1]; } if(tmp.x[i]<0||tmp.x[i]>=n||tmp.y[i]<0||tmp.y[i]>=m)//判断是否越界 break; } if(tmp.x[0]==tmp.x[1]&&tmp.y[0]==tmp.y[1]&&tmp.xx[0]+tmp.xx[1]==0) //两个球在都没有进洞的时候不能在同一个位置 continue; if(v[tmp.x[0]][tmp.y[0]][tmp.x[1]][tmp.y[1]]==1) //两球现在处的位置是否已经出现过 continue; int p; int sum=0; for(p=0; p<2; p++) { for(int k=0; k<2; k++) { if(tmp.x[p]==a2[k]&&tmp.y[p]==b2[k]&&tmp.hole[aa[a2[k]][b2[k]]]==0) //判断球是否到洞的位置,并且洞没有进过球 { tmp.xx[p]=1; //已经进洞的球也标记,以后此球不能再滚动 tmp.hole[aa[a2[k]][b2[k]]]=1; //有球进过的洞标记为1,以后不能再进 } } if(tmp.xx[p]==0) sum=1; //还有球没有进入洞,sum标记为1 } if(sum==0) //sum为0,球已经全部进洞 { flag=1; printf("%d\n",now.step+1); return; } v[tmp.x[0]][tmp.y[0]][tmp.x[1]][tmp.y[1]]=1; tmp.step=now.step+1; Q.push(tmp); } } return ; } int main() { int T; scanf("%d",&T); while(T--) { flag=0; memset(v,0,sizeof(v)); memset(aa,0,sizeof(aa)); scanf("%d%d",&n,&m); int k1=0,k2=0,num=0; for(int i=0; i<n; i++) { scanf("%s",a[i]); for(int j=0; j<m; j++) { if(a[i][j]=='B') //统计球的位置 { a1[k1]=i; b1[k1++]=j; } if(a[i][j]=='H')//统计洞的位置 { a2[k2]=i; b2[k2++]=j; aa[i][j]=num++; //记录是第几个洞,为了区分呢个洞被进(直接坐标记录超时) } } } bfs(); if(flag==0) printf("Sorry , sir , my poor program fails to get an answer.\n"); } return 0; }