题意:在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; }