题目地址:
https://www.acwing.com/problem/content/1100/
1 2 3 4 5 6 7
#############################
1 # | # | # | | #
#####---#####---#---#####---#
2 # # | # # # # #
#---#####---#####---#####---#
3 # | | # # # # #
#---#########---#####---#---#
4 # # | | | | # #
#############################
# = Wall
| = No wall
- = No wall
方向:上北下南左西右东。
上图是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成 m ∗ n m∗n m∗n个方格区域,每个方格区域可以有 0 ∼ 4 0\sim 4 0∼4面墙。注意:墙体厚度忽略不计。
输入格式:
第一行包含两个整数 m m m和 n n n,分别表示城堡南北方向的长度和东西方向的长度。接下来 m m m行,每行包含 n n n个整数,每个整数都表示平面图对应位置的方块的墙的特征。每个方块中墙的特征由数字 P P P来描述,我们用 1 1 1表示西墙, 2 2 2表示北墙, 4 4 4表示东墙, 8 8 8表示南墙, P P P为该方块包含墙的数字之和。例如,如果一个方块的 P P P为 3 3 3,则 3 = 1 + 2 3 = 1 + 2 3=1+2,该方块包含西墙和北墙。城堡的内墙被计算两次,方块 ( 1 , 1 ) (1,1) (1,1)的南墙同时也是方块 ( 2 , 1 ) (2,1) (2,1)的北墙。输入的数据保证城堡至少有两个房间。
输出格式:
共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。
数据范围:
1 ≤ m , n ≤ 50 1≤m,n≤50 1≤m,n≤50
0 ≤ P ≤ 15 0≤P≤15 0≤P≤15
可以用BFS。这里需要将每个数的二进制位与四个方向做个对应, 1 = 2 0 1=2^0 1=20西墙,是第 0 0 0个方向; 2 = 2 1 2=2^1 2=21北墙,是第 1 1 1个方向; 4 = 2 2 4=2^2 4=22东墙,是第 2 2 2个方向; 8 = 2 3 8=2^3 8=23南墙,是第 3 3 3个方向。可以采用一个技巧,令数组 d = [ 0 , − 1 , 0 , 1 , 0 ] d=[0,-1,0,1,0] d=[0,−1,0,1,0],这样 d [ 0 , 1 , 2 , 3 ] d[0,1,2,3] d[0,1,2,3]分别代表的就是西北东南四个墙的方向。代码如下:
#include <iostream>
#include <queue>
using namespace std;
const int N = 55, d[] = {
0, -1, 0, 1, 0};
int m, n;
int a[N][N];
bool st[N][N];
queue<pair<int, int> > q;
int bfs(int x, int y) {
int area = 1;
q.push({
x, y});
st[x][y] = true;
while (!q.empty()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = t.first + d[i], ny = t.second + d[i + 1];
// 不能出界
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
// 不能之前已经访问过
if (st[nx][ny]) continue;
// 不能撞墙
if (a[t.first][t.second] >> i & 1) continue;
q.push({
nx, ny});
st[nx][ny] = true;
area++;
}
}
return area;
}
int main() {
cin >> m >> n;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
int cnt = 0, area = 0;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (!st[i][j]) {
area = max(area, bfs(i, j));
cnt++;
}
cout << cnt << endl;
cout << area << endl;
return 0;
}
时空复杂度 O ( m n ) O(mn) O(mn)。