现在的位置: 首页 > 综合 > 正文

HDU3309Roll The Cube(BFS)

2017年12月12日 ⁄ 综合 ⁄ 共 3303字 ⁄ 字号 评论关闭

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
#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");
    }
}

抱歉!评论已关闭.