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;
}


 

 

posted on 2013-08-02 22:38  you Richer  阅读(168)  评论(0编辑  收藏  举报