Luogu P6892 [ICPC 2014 WF] Baggage 题解
不难猜测的是答案下界为 \(n\),同时我们最后一次移动是把最后面一对 AA/BB 字符移动到前面交界处去。手玩一下样例,有一种通解如下:分别移动最右边的 \(AB\) 和 \(BA\) 到左边和右边,此时中间的部分会变为一个长度 \(n'= n - 4\) 的子问题,同样的每次左移两位,最后移动左边的 \(BB\) 和右边的 \(AA\) 复位。当 \(n = 8\) 时,
\[\begin{aligned}
XXBABABABABABABABA \\
\color{red}{AB} BABABABABABABXXA \\
ABBAXXBABABABAB\color{red}{BA}A \\
ABBAAAAABBBBXXBBAA \\
AAAAAAAABBBBBBBBXX \\
\end{aligned}
\]
类似这样,对于 \(n \geq 8\) 的情况用这种方法递归推广下去,对于 \(n \lt 8\) 的情况要手玩或者暴力打表。
#include <bits/stdc++.h>
using i64 = long long;
int n;
std::vector<std::pair<int, int>> ans;
void dfs(int l, int r) {
if (r - l + 1 == 6) {
ans.push_back({l + 1, l - 2});
ans.push_back({l + 4, l + 1});
ans.push_back({l + 2, l - 4});
return;
}
if (r - l + 1 == 8) {
ans.push_back({l + 5, l - 2});
ans.push_back({l + 2, l + 5});
ans.push_back({l - 1, l + 2});
ans.push_back({l + 6, l - 1});
return;
}
if (r - l + 1 == 10) {
ans.push_back({l + 7, l - 2});
ans.push_back({l + 2, l + 7});
ans.push_back({l + 5, l + 2});
ans.push_back({l - 1, l + 5});
ans.push_back({l + 8, l - 1});
return;
}
if (r - l + 1 == 12) {
ans.push_back({l + 9, l - 2});
ans.push_back({l + 6, l + 9});
ans.push_back({l + 1, l + 6});
ans.push_back({l + 5, l + 1});
ans.push_back({l - 1, l + 5});
ans.push_back({l + 10, l - 1});
return;
}
if (r - l + 1 == 14) {
ans.push_back({l + 7, l - 2});
ans.push_back({l + 4, l + 7});
ans.push_back({l + 11, l + 4});
ans.push_back({l + 2, l + 11});
ans.push_back({l + 8, l + 2});
ans.push_back({l - 1, l + 8});
ans.push_back({l + 12, l - 1});
return;
}
ans.push_back({r - 2, l - 2});
ans.push_back({l + 2, r - 2});
dfs(l + 4, r - 4);
ans.push_back({l - 1, r - 5});
ans.push_back({r - 1, l - 1});
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n;
dfs(1, n * 2);
for (auto i : ans) {
std::cout << i.first << " to " << i.second << "\n";
}
return 0;
}

浙公网安备 33010602011771号