http://acm.hdu.edu.cn/showproblem.php?pid=2952
这道题的简单意思就是问你#把.分成了几部分,所以是广搜,遇到一个#就开始广搜,然后把这些访问过得点改成.并且count+1
我在这道题中遇到的问题是:一定要遇到#之后就把这个点标记成访问过的不然加入队列后,会导致重复访问而超时。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> //泼水原理 /* 要注意的: 1.用vis数组记录访问过的位置,其目的是减少访问量, 一般bfs会出现Memory limit exceed,加到队列里面的节点都要占空间,扩展的节点太多就爆内存 2.一定要在访问过后就立刻标记,而不是在第二次查找下边的点的时候才把当前点标记访问过。 3.用vis数组标记和将图中标记为不可访问的效果是一样的。 */ using namespace std; void bfs(int s,int t); struct point{ int x,y; }; queue<point> que; int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, 1, -1}; int a,b; char G[101][101]; int main(){ int n,ans; scanf("%d",&n); for(int s=0;s<n;s++){ scanf("%d%d",&a,&b); for(int x=0;x<a;x++){ scanf("%s",G[x]); } ans=0; for(int i=0;i<a;i++){ for(int j=0;j<b;j++){ if(G[i][j]=='#'){ bfs(i,j); ans++; } } } printf("%d ",ans); } return 0; } void bfs(int s,int t){ point start; start.x=s; start.y=t; que.push(start); G[s][t]='.'; while(!que.empty()){ point p=que.front(); que.pop(); for(int i=0;i<4;i++){ int xx=p.x+dx[i]; int yy=p.y+dy[i]; if(xx<0||xx>=a)continue; if(yy<0||yy>=b)continue; if(G[xx][yy]=='.')continue; point r; r.x=xx; r.y=yy; que.push(r); G[xx][yy]='.'; } } }