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;
}
posted @ 2025-11-21 10:45  夢回路  阅读(4)  评论(0)    收藏  举报