题目描述 Description
小浣熊松松到他的朋友家别墅去玩,发现他朋友的家非常大,而且布局很奇怪。具体来说,朋友家的别墅可以被看做一个N*M的矩形,有墙壁的地方被标记为’#’,其他地方被标记为’.’。两个格子(a,b)和(c,d)被当做在同一个房间内,当且仅当|a-c|+|b-d|=1。现在松松想知道,有多少个房间。
输入描述 Input Description
第一行包含两个整数,N和M。
接下来N行描述别墅的情况,只包含’*’和’.’。
输出描述 Output Description
输出仅一行,为房间数。
样例输入 Sample Input
3 3
.#.
#.#
.#.
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
对于90%的数据,1<=N,M<=1000;
对于100%的数据,1<=N,M<=2000。
代码
#include <iostream>
#include <queue>
using namespace std;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {-1, 1, 0, 0};
bool vis[2010][2010];
int N, M;
struct node{
int x, y;
}h;
void bfs(int i, int j){ // 执行bfs
queue<node> q; // 创建队列q
int i1;
h.x = j; // 使结构体内部的x,y分别等于传进来的j与i的值,以此作为起点
h.y = i;
q.push(h); // 使结构体f入列
vis[h.y][h.x] = 1; // 标记该点,使之后遍历的时候忽略此点
while(!q.empty()){ // 判断队列是否为空,不为空则执行内部函数
node h1 = q.front(); // 创建结构体h1,使结构体h1的整体等于队列q中的第一个值
q.pop(); // 弹出队列q中的第一个值
for(i1 = 0; i1 < 4; i1++){ // 开始遍历四周的点
node h2;
h2.x = h1.x + dx[i1]; // 构造该点四周的点
h2.y = h1.y + dy[i1];
if(h2.x > 0 && h2.x <= M && h2.y > 0 && h2.y <= N && !vis[h2.y][h2.x]){ // 判断是否可以访问该点
vis[h2.y][h2.x] = 1; // 标记该点,使该点以后不可访问
q.push(h2);
}
}
}
}
int main(){
int i, j, res = 0;
char temp;
cin >> N >> M; // N是y轴上面的数,M是x轴上面的数
for(i = 1; i <= N; i++){
for(j = 0; j < M; j++){
cin >> temp;
if(temp == '#') vis[i][j + 1] = 1;
}
}
for(i = 1; i <= N; i++){ // 一遍遍找能bfs的地方调用bfs
for(j = 1; j <= M; j++){
if(!vis[i][j]){
res++;
bfs(i, j);
}
}
}
cout << res; // 输出房屋数量
return 0;
}