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);
    }
}
原文地址:https://www.cnblogs.com/liyinggang/p/5741981.html