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\n",cnt);

    }

    return 0;

}


 

 

你可能感兴趣的:(find)