• 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);
        }
    }
  • 相关阅读:
    Clipboard.GetImage() Clipboard获取粘贴板内容为null的解决办法
    vs开发 winform 设置winform 获取管理员权限启动
    sql server分配某个用户只对某一个数据库有权限 转载 http://blog.sina.com.cn/s/blog_13554ebc70102wi3h.html
    第一个 谷歌浏览器扩展插件 操作网页
    printDocument设置适应边框打印 特重要 找了半天 设置一个属性即可
    手机网络抓包 转载记录http://blog.csdn.net/skylin19840101/article/details/43485911
    C#合并文件夹图片列表 自定义排版顺序
    ROS nodelet 理解记录
    多线程操作控件属性
    Djianggo 在windows中安装出现报错的解决方案
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5741981.html
Copyright © 2020-2023  润新知