zoukankan      html  css  js  c++  java
  • hdu 1547(BFS)

    Bubble Shooter

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1057    Accepted Submission(s): 454


    Problem Description
    Bubble shooter is a popular game. You can find a lot of versions from the Internet.



    The goal of this game is to clean the bubbles off the field. Every time you just point the cannon to where you want the next bubble to go, and if three or more of bubbles with the same color came together (including the newly shot bubble), they will detonate. After the first explode, if some bubbles are disconnected from the bubble(s) in the topmost row, they will explode too.

    In this problem, you will be given an arranged situation of bubbles in the field and the newly shot bubble. Your program should output the total number of bubbles that will explode.
     
    Input
    There are multiple test cases. Each test case begins with four integers H (the height of the field, 2 <= H <= 100), W (the width of the field, 2 <= W <= 100, in the picture above, W is 10), h (the vertical position of the newly shot bubble, count from top to bottom, and the topmost is counted as 1) and w (the horizontal position of the newly shot bubble, count from left to right, and the leftmost is counted as 1).
    Then H lines follow, the odd lines will contain W characters while the even lines will contain W-1 characters (refer to the picture above). Each character will be either a lowercase from 'a' to 'z' indicating the color of the bubble in that position, or a capital letter 'E' indicating an empty position. You may assure the arranged situation is always valid (all the bubbles are directly or indirectly connected with at least one bubble in the topmost row, and the position of newly shot bubble is never empty).
     
    Output
    For each test case, output an integer indicating how many bubbles will explode.
     
    Sample Input
    2 2 2 1 aa a 3 3 3 3 aaa ba bba 3 3 3 1 aaa ba bba 3 3 3 3 aaa Ea aab
     
    Sample Output
    3 8 3 0
     
    Author
    JIN, Tianpeng
     
    Source
     
    题意:玩泡泡龙,开始是所有的球都是通过六个方向连在一起的,规则是如果现在指定的位置有至少三个球在六个方向组成一个连通分量,这些球就是可以消掉的,消掉这些球之后,如果有些球没有和最上面的那一层相连了,那么就会掉下去,现在给出矩阵的大小和指定的位置,问最多可以消掉多少球?
    题解:这题主要是要弄清泡泡龙六个方向是哪里,要分奇数行和偶数行进行讨论,如果是奇数行,那么他可以和(x,y-1),(x,y+1),(x-1,y-1),(x-1,y),(x+1,y-1),(x+1,y)相连,如果是偶数行,它可以和(x,y-1),(x,y+1),(x+1,y+1),(x+1,y),(x-1,y+1),(x-1,y)相连,先从初始位置做一次bfs,将所有相同颜色并且相连的球标记计数,然后从第一行开始做第二次bfs,将所有能够连通的块都连通,最后统计哪些没有被标记,那么这些球就会掉下去,计数即可.
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <stdlib.h>
    using namespace std;
    const int N = 250;
    int n,m,a,b;
    char graph[N][N];
    bool vis[N][N];
    struct Node{
        int x,y;
    };
    bool check(int x,int y,char c){
        if(x%2){
            if(x<1||x>n||y<1||y>m||vis[x][y]||graph[x][y]=='E'||graph[x][y]!=c) return false;
        }else{
            if(x<1||x>n||y<1||y>=m||vis[x][y]||graph[x][y]=='E'||graph[x][y]!=c) return false;
        }
        return true;
    }
    bool check2(int x,int y){
        if(x%2){
            if(x<1||x>n||y<1||y>m||vis[x][y]||graph[x][y]=='E') return false;
        }else{
            if(x<1||x>n||y<1||y>=m||vis[x][y]||graph[x][y]=='E') return false;
        }
        return true;
    }
    int dir1[][2]={{0,-1},{0,1},{1,1},{1,0},{-1,0},{-1,1}}; ///偶数行
    int dir2[][2]={{0,-1},{0,1},{-1,-1},{-1,0},{1,-1},{1,0}}; ///奇数行
    void bfs(){
        queue<Node> q;
        Node s;
        s.x = a,s.y = b;
        vis[s.x][s.y] = true;
        q.push(s);
        while(!q.empty()){
            Node now = q.front();
            q.pop();
            Node next;
            if(now.x%2==0){
                for(int i=0;i<6;i++){
                    next.x = now.x+dir1[i][0];
                    next.y = now.y+dir1[i][1];
                    if(!check(next.x,next.y,graph[now.x][now.y])) continue;
                    vis[next.x][next.y] = true;
                    q.push(next);
                }
            }else{
                for(int i=0;i<6;i++){
                    next.x = now.x+dir2[i][0];
                    next.y = now.y+dir2[i][1];
                    if(!check(next.x,next.y,graph[now.x][now.y])) continue;
                    vis[next.x][next.y] = true;
                    q.push(next);
                }
            }
        }
    }
    void bfs2(int k){
        queue<Node> q;
        Node s;
        s.x = 1,s.y = k;
        vis[s.x][s.y] = true;
        q.push(s);
        while(!q.empty()){
            Node now = q.front();
            q.pop();
            Node next;
            if(now.x%2==0){
                for(int i=0;i<6;i++){
                    next.x = now.x+dir1[i][0];
                    next.y = now.y+dir1[i][1];
                    if(!check2(next.x,next.y)) continue;
                    vis[next.x][next.y] = true;
                    q.push(next);
                }
            }else{
                for(int i=0;i<6;i++){
                    next.x = now.x+dir2[i][0];
                    next.y = now.y+dir2[i][1];
                    if(!check2(next.x,next.y)) continue;
                    vis[next.x][next.y] = true;
                    q.push(next);
                }
            }
        }
    }
    int main(){
        while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){
            memset(graph,0,sizeof(graph));
            for(int i=1;i<=n;i++){
                scanf("%s",graph[i]+1);
            }
            memset(vis,false,sizeof(vis));
            bfs();
            int ans = 0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    if(vis[i][j]) ans++;
                }
            }
            if(ans<3){
                printf("%d
    ",0);
                continue;
            }
            for(int i=1;i<=m;i++){
                if(graph[1][i]=='E'||vis[1][i]) continue;
                bfs2(i);
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    if(i%2==0&&j==m) continue;
                    if(graph[i][j]=='E') continue;
                    if(!vis[i][j]) ans++;
                }
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    详解 CSS 属性
    【技巧】DataGridView,ListView重新绑定时保持上次滚动位置
    c#自动更新+安装程序的制作 (转)
    C#winform程序安装时自动卸载新版本覆盖旧版本
    C# 操作XML文件,用XML文件保存信息
    c# winform 隐藏tabcontrol标签
    datagridview用get,set访问并加锁,可以控制所有使用datagridview的地方都顺序进行访问
    sql 获取当天开始时间 结束时间
    批量导出指定注册表内容
    sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5741981.html
Copyright © 2011-2022 走看看