ECNA 2017 Problem H Sheba’s Amoebas(简单dfs + dfs序)

本文介绍了一种用于计数图像中闭合环路(代表amoebas)的算法,通过深度优先搜索(DFS)标记每个环路,并确保不重复计数。算法应用于验证Sheba's Amoebas公司发送的Petri dish中amoebas的数量,解决了多个amoebas可能嵌套的问题。

题目链接(不过看的大家可能打不开)

https://codeforces.com/gym/254936

这就是题啦~~
Problem H
Sheba’s Amoebas
After a successful Kickstarter campaign, Sheba Arriba has raised enough money for her mail-order biology
supply company. “Sheba’s Amoebas” can ship Petri dishes already populated with a colony of those tiny
one-celled organisms. However, Sheba needs to be able to verify the number of amoebas her company sends
out. For each dish she has a black-and-white image that has been pre-processed to show each amoeba as a
simple closed loop of black pixels. (A loop is a minimal set of black pixels in which each pixel is adjacent to
exactly two other pixels in the set; adjacent means sharing an edge or corner of a pixel.) All black pixels in
the image belong to some loop.
Sheba would like you to write a program that counts the closed loops in a rectangular array of black and white
pixels. No two closed loops in the image touch or overlap. One particularly nasty species of cannibalistic
amoeba is known to surround and engulf its neighbors; consequently there may be amoebas within amoebas.
For instance, each of the images in Figure H.1 contains four amoebas.
Figure H.1: Two Petri dishes, each with four amoebas.
Input
The first line of input contains two integers m and n, (1 ≤ m, n ≤ 100). This is followed by m lines, each
containing n characters. A ‘#’ denotes a black pixel, a ‘.’ denotes a white pixel. For every black pixel,
exactly two of its eight neighbors are also black.
Output
Display a single integer representing the number of loops in the input.
ECNA 2017 Problem H: Sheba’s Amoebas 15
Sample Input 1 Sample Output 1
12 12
.##########.
#..........#
#..#...##..#
#.##..#..#.#
#......#.#.#
#....#..#..#
#...#.#....#
#..#...#...#
.#..#.#....#
#....#.....#
#.........#.
.#########..
4
Sample Input 2 Sample Output 2
12 10
.#####....
#.....#...
#..#..#...
#.#.#.#...
#..#..#...
.#...#....
..###.....
......#...
.##..#.#..
#..#..#...
.##.......
..........
4

题意:找该图中有几个环,“##”这种不算环
题解:那怎么判环呢,把该环标上dfs序,也就是说每找到一个#,都cnt++,那就是从1到x,最后找到x的时候,发现它能找到1,那么他就构成一个环啦。其余的写法和一般的dfs没啥区别。

#include<bits/stdc++.h>
const int maxn = 120;
using namespace std;

int n,m,vis[maxn][maxn],dep[maxn][maxn],cnt,ans;
int dx[] = {0,0,-1,-1,-1,1,1,1};
int dy[] = {1,-1,0,1,-1,0,-1,1};
char a[maxn][maxn];

void init(){
    ans = 0;
    memset(vis,0,sizeof(vis));
    memset(dep,0,sizeof(dep));
}

void dfs(int x,int y){
    dep[x][y] = ++cnt;
    for(int i = 0 ; i < 8 ; i++){
        int tx = x + dx[i];
        int ty = y + dy[i];
        if(dep[tx][ty] == 1){
            ans++;
        }
        if(vis[tx][ty] || a[tx][ty] == '.' || tx < 1 || tx > n || ty < 1 || ty > m) continue;
        vis[tx][ty] = 1;
        dfs(tx,ty);
    }
}

int main(){
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i = 1; i <= n ;i++){
            scanf("%s",a[i] + 1);
        }
        for(int i = 1; i <= n ; i++){
            for(int j = 1 ; j <= m ;j++){
                cnt = 0;
                if(a[i][j] == '#' && !vis[i][j]){
                    dfs(i,j);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值