https://www.luogu.com.cn/problem/P1457
思路
深搜求出各个房间编号以及大小,前两问解决,三四问,枚举要拆的墙,当然每堵能拆的墙都能转换为相邻某区域的北面或东面,所以只用枚举这两个面,然后按照题目的优先级做好判断,有些坑,第一遍只得了75,下了数据看才知道有地方疏忽了。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 52;
int n, m;
int num, mx, nmx, mj, ci, cj, cc;
int wall[N][N][5];
int id[N][N];
vector <int> area;
int dir[4][2] = { 0, -1,
-1, 0,
0, 1,
1, 0};
void dfs(int x, int y) {
//cout << x << " " << y << endl;
id[x][y] = num;
mj++;
for (int i = 1; i <= 4; i++) {
if (!wall[x][y][i] && !id[x + dir[i - 1][0]][y + dir[i - 1][1]]) {
dfs(x + dir[i - 1][0], y + dir[i - 1][1]);
}
}
}
int main() {
//freopen("in.txt", "r", stdin);
cin >> m >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
int t; cin >> t;
if (t & 1) wall[i][j][1] = 1;
if (t & 2) wall[i][j][2] = 1;
if (t & 4) wall[i][j][3] = 1;
if (t & 8) wall[i][j][4] = 1;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (!id[i][j]) {
num++;
dfs(i, j);
area.push_back(mj);
mx = max(mx, mj); mj = 0;
}
}
// for (int i = 0; i < num; i++)
// cout << area[i] << " ";
// cout << endl;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
for (int k = 2; k <= 3; k++)
if (wall[i][j][k]) {
if (id[i][j] != id[i + dir[k-1][0]][j + dir[k-1][1]]) {
int ns = area[id[i][j]-1] + area[id[i + dir[k-1][0]][j + dir[k-1][1]]-1];
// cout << ns << " " << nmx << " " << i << " " << j << endl;
if (ns > nmx) {
ci = i, cj = j, cc = k;
nmx = ns;
} else if (ns == nmx) {
if (j < cj) {
ci = i, cj = j, cc = k;
} else if (j == cj && i > ci) {
ci = i, cj = j, cc = k;
}
}
}
}
cout << num << endl;
cout << mx << endl;
cout << nmx << endl;
cout << ci << " " << cj << " " << (cc == 2 ? "N":"E") << endl;
return 0;
}