HDU 1547 Bubble Shooter(BFS)

HDU 1547 Bubble Shooter(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=1547

题意:

        如下图的游戏,R*C的棋盘格局,左上角是第1行1列,其中奇数行可以放C个不同颜色的气球,偶数行可以放C-1个不同颜色的气球.且如果我们新打一个气球到给定位置,>=3个相连的同颜色气球会爆炸,且如果某一块气球没有和最顶端的墙想连也会爆炸.

        现在给出了当前气球的布局,以及最近一次射击的气球在布局中的位置,问你这次有多少个气球会爆炸。


分析:

       大致思想是先用BFS从新气泡点走相同的颜色,且记录走过的点并把该点置为空(E),然后最终如果相同颜色气球数<3的话,就还原气球颜色。这样就找出了同色相连球的数目。

       下一步找悬空球的数目:从顶端非空的格子遍历,每遍历一个气球就把该点置为E,然后朝它的6个方向继续BFS即可。返回本次遍历所消除的气球数(其实就是还剩下的气球数)。最后用初始的气球总数减去我们C次BFS的返回值之和,就是悬空的气球个数。

       注意:球可以往6个方向走,且奇数和偶数行的球走法不同.

       写代码的时候出了很多小错误,其中有一个是:原题中的偶数行和奇数行处理不同,但是由于代码中我们是从0开始算行数的,导致了原题的偶数行变成了奇数行,原题的奇数行变成了偶数行.

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=105;
int R,C;
char map[maxn][maxn];
int dir[2][6][2]=
{
    {{0,-1},{0,1},{-1,0},{1,0},{-1,1},{1,1} },  //偶数行:左 右 左上 左下 右上 右下
    {{0,-1},{0,1},{-1,-1},{1,-1},{-1,0},{1,0} } //奇数行:左 右 左上 左下 右上 右下
};

int BFS(bool flag,int sr,int sc)//flag=true时,表消除新球的同色球,否则表消除相连的所有球
{
    int sum=0, s[maxn*maxn];     //错误,s数组开小了
    queue<int> Q;
    Q.push(sr*C+sc);
    char ch=map[sr][sc];    //记录我们消除的初始颜色
    map[sr][sc]='E';        //置空
    s[sum++]=sr*C+sc;       //记录被置空的点
    while(!Q.empty())
    {
        int pos=Q.front();Q.pop();
        int r=pos/C, c=pos%C;
        for(int d=0;d<6;d++)
        {
            int nr=r+dir[(r+1)%2][d][0], nc=c+dir[(r+1)%2][d][1];
            if(nr<0||nr>=R||nc<0||nc>=C-nr%2||map[nr][nc]=='E') continue;//错误,这里忘了nc>=C-nr%2 且我们行数是从0开始算的
            if(flag && map[nr][nc]!=ch) continue;
            map[nr][nc]='E';
            Q.push(nr*C+nc);
            s[sum++]=nr*C+nc;
        }
    }
    if(flag && sum<3) for(int i=0;i<sum;i++) map[s[i]/C][s[i]%C]=ch; //sum<3,还原球状态
    return sum;
}
int main()
{
    int sr,sc;
    while(scanf("%d%d%d%d",&R,&C,&sr,&sc)==4)
    {
        sr--,sc--; //错误,这里忘了
        for(int i=0;i<R;i++) scanf("%s",map[i]);
        int all=0;//初始总球数
        for(int i=0;i<R;i++)
        for(int j=0;map[i][j];j++)if(map[i][j]>='a'&&map[i][j]<='z')
            all++;
        BFS(true,sr,sc);
        int ans=0;
        for(int j=0;j<C;j++)if(map[0][j]!='E')      //错误,这里只处理第0行
                ans+=BFS(false,0,j);
        printf("%d\n",all-ans);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值