• HDU 4414 Finding crosses (DFS + BFS)


    题意:在N*N的图中,找出孤立存在的十字架的个数。十字架要求为正十字,孤立表示组成十字架的‘#的周围的一格再无’#‘。

    dfs找出在中心的‘#’(周围四格也为‘#'),则缩小了搜索范围,再bfs找出是否是符合要求。

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char map[55][55];
    int n,cnt,head,tail,vis[55][55],center[55][55];
    int dirx[4] = {1,-1,0,0};
    int diry[4] = {0,0,1,-1};
    
    struct Queue {
        int x,y;
    } q[11111];
    
    bool go(int x,int y) {
        if(x < 0 || x >=n || y < 0 || y >= n) return false;
        if(vis[x][y]) return false;
        if(map[x][y] != '#') return false;
        return true;
    }
    void dfs(int x,int y) {
        int xx,yy;
        int i,p = 0;
        for(i=0; i<4; i++) {
            xx = x + dirx[i];
            yy = y + diry[i];
            if(go(xx,yy)) {
                p ++ ;
                vis[xx][yy] = 1;
                dfs(xx,yy);
            }
        }
        if(p == 3) {
            center[x][y] = 1;
        }
    }
    
    void bfs(int x,int y) {
        head = 0;
        tail = 0;
        q[head].x = x;
        q[head++].y = y;
        vis[x][y] = 1;
        int cut = 4;  //dfs计算后,确保至少长度为三的十字架
        while(head != tail) {
            Queue t = q[tail++];
            Queue tt;
            int num = 0;
            for(int i=0; i<4; i++) { //下 上 右 左
                tt.x = t.x + dirx[i];
                tt.y = t.y + diry[i];
                if(go(tt.x,tt.y)) {
                    num++;
                    vis[tt.x][tt.y] = 1;
                    q[head++] = tt;
                }
            }
            if(num == 1) cut ++;
        }
        cut = cut / 4; // 层数
        if(cut * 4 + 1 == head) cnt ++;
    }
    
    int main() {
        while(cin >> n && n) {
            cnt = 0;
            memset(center,0,sizeof(center));
            for(int i=0; i<n; i++) {
                scanf("%s",map[i]);
            }
            memset(vis,0,sizeof(vis));
            for(int i=0; i<n; i++) {
                for(int j=0; j<n; j ++) {
                    if(map[i][j] == '#' && vis[i][j] == 0) {
                        vis[i][j] = 1;
                        dfs(i,j);
                    }
                }
            }
            memset(vis,0,sizeof(vis));
            for(int i=0; i<n; i++) {
                for(int j=0; j<n; j ++) {
                    if(center[i][j] == 1 && vis[i][j] == 0) {
                        memset(q,0,sizeof(q));
                        bfs(i,j);
                    }
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }


  • 相关阅读:
    C 语言 静态库和动态库的创建和应用
    C++ 中英文术语对照
    下午
    [转]内核 do_fork 函数源代码浅析
    关于C#反射机制,自己写的
    获取字符串中数字
    关于C#反射机制,来源于网络
    关于 Nhinernate 的one to one(转载)
    鼠标坐标的记录
    关于C#中hibernate.cfg.xml动态加载问题
  • 原文地址:https://www.cnblogs.com/riskyer/p/3233821.html
Copyright © 2020-2023  润新知