HDU 4414 Finding crosses(搜索)
【题目大意】
给你一张n*n的图,由o #这两个元素组成,让我们找其中有多少十字架。 十字架由#构成
十字架的纵向长度等于横向长度 , 且这个长度要为大于等于3的奇数。
构成十字架的#周围不能有多余的#
如图1满足条件, 图二不满足,图三不满足,图四不满足, 这三个不满足的条件都是有了多余的#;
【解法】
对每个有#元素的位置bfs , 一层一层的扩展,每次扩展检测周围是否有多余的#,没有就继续扩展, 有就返回0,不能扩展了就判断是否为合格的十字架。
【源代码】
#include <iostream> #include <cstdio> using namespace std; char map[55][55]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int n; bool bfs(int a,int b){ int ans = 0; int cnt = 0; for(int i=1;i<=25;i++){ int step = 0; for(int j=0;j<4;j++){ int nx = a+dx[j]*i; //*i, 实现一层层扩展 int ny = b+dy[j]*i; if(nx<0 || nx>=n|| ny<0|| ny>=n) continue; if(map[nx][ny] == '#'){ step++; if(j==2 || j==3){ if(ny>0 && map[nx][ny-1] == '#' || ny<n-1 &&map[nx][ny+1]=='#') //判断相邻的位置是否有 # return false; } else{ if(nx>0 && map[nx-1][ny] == '#' || nx<n-1 &&map[nx+1][ny]=='#') //判断相邻的位置是否有 # return false; } cnt++; } } if(step == 0) break;不能扩展了就跳出循环 if(step != 4) //说明没有完全扩展 return false; } if(cnt%2==0&& cnt>0) return true; else return false; } int main(){ while(scanf("%d",&n)!=EOF && n){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ scanf(" %c",&map[i][j]); } } int ans = 0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++) { if(map[i][j] == '#'){ ans+= bfs(i,j); } } } printf("%d\n",ans); } return 0; }