hdu 3309 Roll The Cube 广搜

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<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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值