例题:
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。
你站在其中一块黑色的瓷砖上,只能向相邻(上下左右四个方向)的黑色瓷砖移动。
请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
分析:
1.特点是把从起点出发能到达的点全部放入队列中,每个点只能入队一次,出队的时候将数目加一。就可以统计所有点连通的最大数目了。
2.使用数组来模拟队列需要注意数组的大小为N*N,hh=0,tt=0 while(hh<=tt){}.
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=30;
#define x first
#define y second
typedef pair<int,int> PII;
char g[N][N];
bool st[N][N];
PII q[N*N];
int res; //记录连通块的数目
int n,m;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
void bfs(int sx,int sy)
{
res=0;
memset(st,0,sizeof st);
st[sx][sy]=true;
int hh=0,tt=0;//用数组来模拟队列
q[0]={sx,sy};
while(hh<=tt)
{
auto t=q[hh++];
res++; //每出队一个数,连通块中的数就加一
for(int i=0;i<4;i++)
{
int x=t.x+dx[i],y=t.y+dy[i];
if(x<0 || x>=n || y<0 || y>=m) continue;
if(st[x][y]) continue;
if(g[x][y]=='#') continue;
st[x][y]=true;
q[++tt]={x,y};
}
}
}
int main()
{
while(cin>>m>>n,n || m) //读入数据的方式
{
for(int i=0;i<n;i++) cin>>g[i];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(g[i][j]=='@')
{
bfs(i,j);
}
cout<<res<<endl;
}
return 0;
}