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

Zhejiang Provincial Programming Contest 2006

题意:玩泡泡龙,开始是所有的球都是通过六个方向连在一起的,规则是如果现在指定的位置有至少三个球在六个方向组成一个连通分量,这些球就是可以消掉的,消掉这些球之后,如果有些球没有和最上面的那一层相连了,那么就会掉下去,现在给出矩阵的大小和指定的位置,问最多可以消掉多少球?

题解:这题主要是要弄清泡泡龙六个方向是哪里,要分奇数行和偶数行进行讨论,如果是奇数行,那么他可以和(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\n",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\n",ans);
    }
}
时间: 2024-08-27 17:23:30

hdu 1547(BFS)的相关文章

hdu 1175 bfs 转弯题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 和之前的1728类似.就是判断转弯数,建立一个用于记录转弯数的数组.. 还有就是对于特殊情况要进行考虑,比如起点与终点相同的情况,对于本题来说是不可以消去的应该输出NO.还有就是起点或终点是零这也是不行的,因为0代表没有棋子... 还有在判断能不能走的时候要小心,对于判断条件一定要小心,不要图赶快写.. 错误的地方都写在注释中了.. 代码: // hdu 1175 bfs 转弯数 //1.起点

Saving Princess claire_(hdu 4308 bfs模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=4308 Saving Princess claire_ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2305    Accepted Submission(s): 822 Problem Description Princess claire_ wa

HDU 1072 bfs

Nightmare Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7083    Accepted Submission(s): 3409 Problem Description Ignatius had a nightmare last night. He found himself in a labyrinth with a tim

hdu 1252 BFS

1 /* 2 题意:给出一个m*m矩阵表示的完全图,且每个点都有自环,每条边都有一种颜色:有三个玩家ABC的三张纸片分别初始在 3 某三个位置(可以重叠),纸片可以沿着边走一步,可以走的路径的规则为:若A要走到某个点i,则A-i的颜色要和B-C的颜 4 色相同:问最少要走多少步.(题意太难懂了,看了别人的说明才弄懂了题意) 5 6 题解:BFS 7 首先初步分析题意似乎很难用图论来解决,那么就是搜索/DP/数据结构,然后从搜索方面去思考的话,就是要找状态,然 8 后初步列出所有信息,三个点得位置

hdu 4707 bfs

bfs基础算法水题 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include<queue> using namespace std; const int Max = 1e5+50; int dist[Max]; vector<int> t

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

hdu 1226 BFS + bfs记录路径

http://acm.hdu.edu.cn/showproblem.php?pid=1226 为了省空间,可以用vis数组初始化的时候初始化为-1, 发现一个BFS容易错的地方 开始一直WA在这里:就是我int tp=q.front();之后马上q.pop():了,然后才去判断是不是符合条件以break,这样就不能根据q.empty()==1认为没有找到ans 因为这里WA了 其实也可以vis[0] == -1来判断 比较不理解的是 当n==0的时候 %n==0的时候怎么处理 //#pragma

hdu 5025 BFS + 优化 广东区域赛网赛

http://acm.hdu.edu.cn/showproblem.php?pid=5025 TLE了好几次 写的时候,问题在于, 1.钥匙怎么处理 参考了他人的写法,vis[key_num][i][j],相当于将图多维化,这样就可以判重了,否则只是按照普通的BFS,钥匙数不同的时候,可以重复,这个代码难易表达出来 另外此处一个很好的优化,当cost_now<cost[key_now][x_now][y_now]的时候,才q.push(Node)  这个剪枝很好啊 2.蛇怎么处理 没蛇的话,第一

hdu 1430 (BFS 康托展开 或 map )

第一眼看到这题就直接BFS爆搜,第一发爆了内存,傻逼了忘标记了,然后就改,咋标记呢. 然后想到用map函数,就8!个不同的排列,换成字符串用map标记.然后又交一发果断超时,伤心,最恨超时,还不如来个wa算了. 然后卡着了,后来上网上搜了,要用康托展开,康托展开是什么鬼?然后学习了一下,就是个映射,感觉和map差不多. http://blog.csdn.net/zhongkeli/article/details/6966805这个学习一下康托展开. 其实本题的关键不是康托展开,而是置换. 以12