官方题解|捉迷藏
2025-04-28 12:42:41
发布于:浙江
11阅读
0回复
0点赞
模拟
本题聚焦于地图变换与连通块划分问题,目标是判断能否借助特定的行、列交换操作,将给定地图分割为两个或更多的连通块。
-
存在行列均含障碍物的点的情形:若地图中存在某个点,其所在行与列均包含障碍物,处理过程相对简单。可以先将需要分隔的物品移动至地图的四个角落, 随后利用这些障碍物将物品包围起来,以此实现地图的分隔。
-
不存在行列均含障碍物的点的情形:当不存在满足上述条件的点时,经推导可知,所有障碍点能够通过一定的移动,组合形成一个矩形。 在此情况下,核心任务转变为判断能否借助这个矩形,将地图中的空白点分割成两个或更多的连通块。
可以证明对于 1 情况,最多移动 4 次,对于 2 情况,最多移动 2 次。
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
using i32 = int32_t;
vector<pair<int, int> > dd = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void solve() {
int n, m;
cin >> n >> m;
vector<string> s(n + 1);
for (int i = 1; i <= n; i++) {
cin >> s[i];
s[i] = " " + s[i];
}
vector<int> r(n + 2), l(m + 2);
iota(r.begin(), r.end(), 0);
iota(l.begin(), l.end(), 0);
vector<tuple<char, int, int> > op;
auto get_x_y = [&](int x, int y) {
x = r[x];
y = l[y];
return s[x][y];
};
auto swapr = [&](int x, int y) {
if (x == y) return;
op.emplace_back('r', x, y);
swap(r[x], r[y]);
};
auto swapl = [&](int x, int y) {
if (x == y) return;
op.emplace_back('l', x, y);
swap(l[x], l[y]);
};
auto run = [&]() {
int xx, yy;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (get_x_y(i, j) == 'X') xx = i, yy = j;
}
}
vector<vector<int> > vis(n + 1, vector<int>(m + 1));
auto can_reach = [&](int x, int y) {
return x > 0 && x <= n && y > 0 && y <= m && get_x_y(x, y) == '.' && !vis[x][y];
};
queue<pair<int, int> > q;
q.emplace(xx, yy);
while (!q.empty()) {
auto [x,y] = q.front();
q.pop();
vis[x][y] = 1;
for (auto [dx , dy]: dd) {
int ddx = dx + x, ddy = dy + y;
if (can_reach(ddx, ddy)) {
q.emplace(ddx, ddy);
vis[ddx][ddy] = 1;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (get_x_y(i, j) == '.' && !vis[i][j]) {
cout << "Yes" << endl;
cout << op.size() << endl;
for (auto [c , x , y]: op) {
cout << c << " " << x << " " << y << endl;
}
cout << i << " " << j << endl;
return;
}
}
}
cout << "No" << endl;
};
auto rz = [&](int x, int y) {
swapl(1, y);
swapr(1, x);
for (int k = 1; k <= n; k++) {
if (get_x_y(k, 1) == '#') {
swapr(2, k);
break;
}
}
for (int k = 1; k <= m; k++) {
if (get_x_y(1, k) == '#') {
swapl(2, k);
break;
}
}
run();
};
vector<int> rr(n + 1), ll(m + 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (get_x_y(i, j) == '#') {
rr[i]++, ll[j]++;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if ((get_x_y(i, j) == '.' || get_x_y(i, j) == 'X') && ll[j] && rr[i]) {
rz(i, j);
return;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (get_x_y(i, j) == 'X') {
rz(i, j);
return;
}
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
}
这里空空如也
有帮助,赞一个