hdu4527小明系列故事——玩转十滴水 (BFS+DFS)

Problem Description
  小明最近喜欢上了一个名为十滴水的游戏。


  游戏是在一个6*6的方格内进行的,每个格子上有一滴水或者没有水滴。水滴分为四个等级1~4。初始时你有十滴水,通过把水加入格子内的水滴,会让水滴升1级。你也可以把水放到空格子内,这样会在这个格子里面产生一个1级的水滴。当水滴等级大于4时则会爆裂为四个小水滴,并向四个方向飞溅。每个飞溅的小水滴碰到其他水滴后会融入其中,使其升一级或者爆裂,以此类推。飞溅的小水滴互不干扰,运动速度相等(1秒可以移动一个格子的距离)。水滴爆裂后就消失掉了。

Input
题目包含多组测试用例;
对于每组数据,首先是6行,每行有6个整数数字,每个数字的范围为0~4;当数字为0时,表示空格子,当数字为1~4时,表示1~4级的水滴;
然后第七行是一个整数m,表示有m个操作;接下来是m行,每行有两个整数x, y ,表示在(x,y)放入一滴水。
特别说明:每次都是在全部的水滴静止后才进行下一次操作,也就是说只有在方格内没有任何飞溅的小水滴时才能放入一滴水。

[Technical Specification]
1 <= m <= 10
1 <= x, y <= 6

Output
对于每组测试数据,请输出m个操作之后6*6方格内水滴的样子,每组数据的输出后面跟着一个空行。

Sample Input
  
  
0 0 0 4 0 4 0 0 0 0 0 0 1 0 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 6 0 0 0 4 0 4 0 2 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 6 2 2 0 2 0 3 3 3 0 1 3 1 2 2 2 4 0 4 2 4 4 2 2 3 3 3 2 4 0 1 1 3 4 3 0 1 6 5 3 5 3 3 3 3 2 2 1 6 3

Sample Output
  
  
0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 2 0 3 0 0 0 4 3 2 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 4 4 0 0 0 0 3
Hint
第一组数据: (1,6)爆裂,然后在第二秒(1,4)(2,6)爆裂,在第四秒,两滴水同时到达(3,4), (3,4)变成了6,爆裂,然后在第七秒(3,1)(6,4)变成了2。
  思路:加一滴水后能暴裂就加入队列或着是暴裂后的每一步走向位置为0时也加入队列。
注意点:每一步都要控制一样的时间。
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
typedef struct nn
{
    int x,y,dire;
}node;
queue<node> Q[2];//用2个队列是为了控制好一个队列里面是同一时间走一步
int map[8][8],vist[8][8];
int k,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//k表示第k个队列

void bfs()
{
    int e,tx,ty;
    node q,p;
    while(!Q[k].empty())//队列放的位置在map中的数字只有0或大于4
    {
        q=Q[k].front(); Q[k].pop();
        vist[q.y][q.x]=0;
        if(map[q.y][q.x]>4)//当可以暴破时
        {
            map[q.y][q.x]=0;//把当前点变为0
            for(e=0;e<4;e++)//向4个方向走一步
            {
                tx=q.x+dir[e][0]; ty=q.y+dir[e][1];
                if(tx>0&&ty>0&&tx<=6&&ty<=6)
                {
                    p.x=tx; p.y=ty; p.dire=e;  //记录方向和位置
                    if(map[ty][tx]==0)  //当等于0时,直接放入下一个队列中
                    Q[k*-1+1].push(p);
                    else if(map[ty][tx]+1<=4)  //当走向这个点时有值,但不能暴,加个1,不放入队列
                    map[ty][tx]+=1;
                    else       //当可以暴破时
                    {
                        map[ty][tx]+=1;
                        if(vist[ty][tx]==0)  //这里一定要控制,不能一个队列放两个相同的位置
                        {
                            vist[ty][tx]=1;
                            Q[k*-1+1].push(p); //放入下一个队列中
                        }
                    }
                }
            }
        }
        else //当前点为0时,下面的步骤和上面的相同
        {
            tx=q.x+dir[q.dire][0];ty=q.y+dir[q.dire][1];
            if(tx>0&&ty>0&&tx<=6&&ty<=6)
                {
                    p.x=tx;p.y=ty;p.dire=q.dire;
                    if(map[ty][tx]==0)
                    Q[k*-1+1].push(p);
                    else if(map[ty][tx]+1<5)
                    {
                        map[ty][tx]+=1;
                    }
                    else
                    {
                        map[ty][tx]+=1;
                        if(vist[ty][tx]==0)
                        {
                            vist[ty][tx]=1;
                            Q[k*-1+1].push(p);
                        }
                    }
                }
        }
    }
    k=k*-1+1;//下一个队列
    if(!Q[k].empty())
        bfs();
}
int main()
{
    int x,y,m;
    node q;
    while(scanf("%d",&map[1][1])>0)
    {
        for(y=1;y<=6;y++)
        for(x=1;x<=6;x++)
        if(y!=1||x!=1)
        scanf("%d",&map[y][x]);
        scanf("%d",&m);
        k=0;
        while(!Q[k].empty())
            Q[k].pop();
        while(!Q[k*-1+1].empty())
            Q[k*-1+1].pop();
        while(m--)
        {
            scanf("%d%d",&y,&x);
            map[y][x]+=1;
            if(map[y][x]>4)
            {
                memset(vist,0,sizeof(vist));
                q.y=y;q.x=x; vist[y][x]=1;
                Q[k].push(q);
                bfs();
            }
        }
        for(y=1;y<=6;y++)
        {
            printf("%d",map[y][1]);
            for(x=2;x<=6;x++)
            printf(" %d",map[y][x]);
            printf("\n");
        }
        printf("\n");
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值