城堡问题
题目描述
1 2 3 4 5 6 7
#############################
1 # | # | # | | #
#####---#####---#---#####---#
2 # # | # # # # #
#---#####---#####---#####---#
3 # | | # # # # #
#---#########---#####---#---#
4 # # | | | | # #
#############################
# = Wall
| = No wall
- = No wall
方向:上北下南左西右东。
上图是一个城堡的地形图。
城堡被分割成 m×n 个方格区域,每个方格区域可以有 0∼4 面墙。
请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。
注意:墙体厚度忽略不计,输入数据保证存在最外层的一圈墙。
输入格式
第一行包含两个整数 m 和 n,分别表示城堡南北方向的长度和东西方向的长度。
接下来 m 行,每行包含 n 个整数,每个整数都表示平面图对应位置的方块的墙的特征。
每个方块中墙的特征由数字 P 来描述,我们用 1 表示西墙,2 表示北墙,4 表示东墙,8 表示南墙,P 为该方块包含墙的数字之和。
例如,如果一个方块的 P 为 3,则 3=1+2,该方块包含西墙和北墙。
城堡的内墙被计算两次,方块 (1,1) 的南墙同时也是方块 (2,1) 的北墙。
输入的数据保证城堡至少有两个房间,且城堡最外圈一定有墙。
输出格式
共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。
输入输出样例
输入#1
4 7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13
输出#1:
5
9
数据范围
对于 100% 的数据,保证 1≤m,n≤50,0≤P≤15。
提示
样例中的城堡如下图所示:
大体思路
先将在每个方向开墙的对应的数值算出,我们可以创立一个三维数组,前两位用来存储对应房间的坐标,后一位表示当前格子的墙的状态(1,2,3,4各代表一个方向有墙),再进行基本的dfs步骤就可以了。
代码奉上
#include "bits/stdc++.h"
using namespace std;
const int N = 60 + 8;
int m, n, room, step, maxn;
int xx[5] = {0,0,1,0,-1}, yy[5] = {0,1,0,-1,0};
int a[N][N], c[N][N][8];
bool vis[N][N]; //用一个bool类型的数组判断哪些格子已经走过了
void dfs(int x, int y) {
maxn = max(step,maxn); //比较房间的大小,并更新
for(int i=1; i<=4; i++) { //深搜核心步骤
int dx = x + xx[i],dy = y + yy[i];
if(dx < 1 || dx > n || dy < 1 || dy > m) continue; //判断是否跃出格子的边界
if(c[x][y][i] == 0 && vis[dx][dy] == false) { //判断格子是否走过
vis[dx][dy] = true; //将已走过的格子标记
step++; //刷新房间大小
dfs(dx,dy);
}
}
return ;
}
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cin>>a[i][j]; //输入格子的数,并判断每个格子在各个方向的墙的状态
if(a[i][j] == 4||a[i][j] == 5||
a[i][j] == 6||a[i][j] == 7||
a[i][j] == 12||a[i][j] == 13||
a[i][j] == 14||a[i][j] == 15) {
c[i][j][1]++;
}
if(a[i][j] == 8||a[i][j] == 9||
a[i][j] == 10||a[i][j] == 11||
a[i][j] == 12||a[i][j] == 13||
a[i][j] == 14||a[i][j] == 15) {
c[i][j][2]++;
}
if(a[i][j] == 1||a[i][j] == 3||
a[i][j] == 5||a[i][j] == 7||
a[i][j] == 9||a[i][j] == 11||
a[i][j] == 13||a[i][j] == 15) {
c[i][j][3]++;
}
if(a[i][j] == 2||a[i][j] == 3||
a[i][j] == 6||a[i][j] == 7||
a[i][j] == 10||a[i][j] == 11||
a[i][j] == 14||a[i][j] == 15) {
c[i][j][4]++;
}
}
}
//判断完成后进入dfs
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(vis[i][j] == false) {
step = 1; //将每一个房间的大小初始化为1格
vis[i][j] = true; //将已走过的格子标记
dfs(i,j);
room++; //储存房间数
}
}
}
cout<<room<<endl<<maxn; //输出
return 0;
}