您的位置:首页 > 其它

hdu 3309 Roll The Cube(bfs)

2015-08-11 23:46 405 查看
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.


题意:同时控制两个球,把他们移动到洞里 ,球是同时运动的,当一个球到洞了后,另一个球可以从这里经过。

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <queue>

using namespace
std;

int dir[4][2] = {0,1,1,0,0,-1,-1,0};

char map[24][24];

bool vis[24][24][24][24];

int n,m;

struct node

{

int x[2],y[2]; //两个球坐标

bool ball[2]; //球的状态

bool hole[2]; //洞的状态

int step;

node()

{

ball[0]=ball[1]=hole[0]=hole[1]=false;

step=0;

}

void init()

{

ball[0]=ball[1]=hole[0]=hole[1]=false;

step=0;

}

};

node start;

bool check(node &a)

{

for (int i=0; i<2; i++)

{

if(a.x[i]<0 ||a.x[i]>=n || a.y[i]<0
|| a.y[i]>=m)

return
false;

}

if(a.x[0]==a.x[1]&& a.y[0]==a.y[1]
&& a.ball[0]==a.ball[1] && a.ball[0]==0)

return
false;

if(vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]])

return
false;

return
true;

}

int bfs()

{

memset(vis,0,
sizeof(vis));

queue<node>q;

q.push(start);

vis[start.x[0]][start.y[0]][start.x[1]][start.y[1]]=true;

node temp;

while (!q.empty())

{

start=q.front();

q.pop();

for (int i=0; i<4; i++)

{

temp=start;

temp.step++;

for (int j=0; j<2; j++)//对两个球进行移动

{

if(!temp.ball[j])

{

temp.x[j]+=dir[i][0];

temp.y[j]+=dir[i][1];

if(map[temp.x[j]][temp.y[j]]=='*')

{

temp.x[j]-=dir[i][0];

temp.y[j]-=dir[i][1];

}

}

}

if(check(temp))

{

vis[temp.x[0]][temp.y[0]][temp.x[1]][temp.y[1]]=true;

bool flag=true;

for (int j=0; j<2; j++) //检查球是否进洞

{

int k=map[temp.x[j]][temp.y[j]]; //判断第k个洞的状态

if(k<2 && !temp.hole[k])

{

temp.hole[k]=1;

temp.ball[j]=1;

}

if(!temp.ball[j])

flag=false;

}

if(flag)
//都进洞了

return temp.step;

q.push(temp);

}

}

}

return -1;

}

int main()

{

int t,cnt;

scanf("%d",&t);

while (t--)

{

scanf("%d%d",&n,&m);

getchar();

cnt=0;

bool flag=false;

for (int i=0; i<n; i++)

{

for (int j=0; j<m; j++)

{

scanf("%c",&map[i][j]);

if(map[i][j]=='B' && !flag)

{

start.x[0]=i;

start.y[0]=j;

flag=true;

}

else
if(map[i][j]=='B' && flag)

{

start.x[1]=i;

start.y[1]=j;

}

if(map[i][j]=='H')

{

map[i][j]=cnt++;

}

}

getchar();

}

start.init();

int ans=bfs();

if(ans!=-1)

printf("%d\n",ans);

else

printf("Sorry , sir , my poor program fails to get an answer.\n");

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: