AcWing 1359. 洛谷P1457 城堡
解题思路
并查集
维护。这题我们如果注意一点细节,也是可以让代码变得很简洁的:
当移除方法不唯一时,优先选择对应方格区域更靠西的墙
如果仍存在多解,选择对应方格区域更靠南的墙。
在此基础上,还存在多解,那么优先选择北面的墙。
可爱的并查集
初始化不可以把存连通块大小的数组
代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 55, M = N * N;
int p[M], n, m, g[N][N], sz[M];
int find(int x)
{
if (x == p[x]) return x;
return p[x] = find(p[x]);
}
int main()
{
scanf("%d%d", &m, &n);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
scanf("%d", &g[i][j]);
for (int i = 0; i < n * m; i ++ ) p[i] = i, sz[i] = 1;
int cnt = n * m, max_area = 1;
int dx[] = {-1, 0}, dy[] = {0, 1}, dw[] = {2, 4};
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
for (int k = 0; k < 2; k ++ )
{
if (g[i][j] & dw[k]) continue ;
int x = i + dx[k], y = j + dy[k];
if (x < 0 || x >= n || y < 0 || y >= m) continue ;
int u = i * m + j, v = x * m + y;
u = find(u), v = find(v);
if (u != v) {
p[u] = v, sz[v] += sz[u];
-- cnt, max_area = max(max_area, sz[v]);
}
}
printf("%d\n%d\n", cnt, max_area);
max_area = 0;
int rx, ry, rw;
for (int j = 0; j < m; j ++ )
for (int i = n - 1; ~i; i -- )
for (int k = 0; k < 2; k ++ )
{
if (!g[i][j] & dw[k]) continue ;
int x = i + dx[k], y = j + dy[k];
if (x < 0 || x >= n || y < 0 || y >= m) continue ;
int u = i * m + j, v = x * m + y;
u = find(u), v = find(v);
if (u != v) {
int ar = sz[v] + sz[u];
if (ar > max_area) max_area = ar, rx = i + 1, ry = j + 1, rw = k;
}
}
printf("%d\n%d %d %c\n", max_area, rx, ry, (rw ? 'E' : 'N'));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)