河外塔(加强版)C++ 解题思路 - ZSHOI-R1 题解
"用C++讲解以下题目:\n# [ZSHOI-R1] 河外塔(加强版)\n\n## 题目背景\n\n河内塔(又称汉诺塔)问题,就是在一块木板上有三个立柱,在柱 1 上放着三个圆盘,小的在上面,大的在下面(初始状态)。让被试将在柱 1 上的三个圆盘移到柱 3 上面(目标状态)。条件是:每次只能移动任何一个柱子上面的一个圆盘,但大的圆盘不能放在小的圆盘上。\n\n通用问题解决者的解决过程即是手段——目的分析的策略。\n\n## 题目描述\n\n但是,你可能没有听过河外塔问题。虽然但是,好像并没有河外塔问题。于是,伟大的 X_Xy 决定创造一个河外塔问题。\n\n既然是河内塔问题的延申,就得有些一样的东西:有三个柱子 \n$A$,$B$ 和 $C$ ,以及 $n$ 个圆盘,其中编号为 $i$ 的圆盘的半径长为 $i$,这些圆盘最开始都在 $A$ 上,最终都要顺序(即从上往下从小到大)地移到 $C$ 上。\n\n既然是河内塔问题的延伸,就得有些不同的东西:最开始在 $A$ 上面的圆盘并不是顺序的,由于这个限制,我们也不在意移动过程中的顺序,也就意味着你可以将一个大的圆盘放在小的圆盘上。\n\n但是 X_Xy 很懒,他只想让你操作至多 $10^6$ 次。\n\n## 输入格式\n\n输入共两行。\n\n第一行有一个数 $n$,表示圆盘的数量。\n\n第二行有 $n$ 个数,表示 $A$ 上所有的圆盘从上往下的标号,保证圆盘构成一个 $1\sim n$ 的排列。\n\n## 输出格式\n\n共若干行。\n\n第一行有一个数 $tot$,表示你的操作数。\n\n接下来的第 $2$ 到第 $tot$ 行,每行两个用空格隔开的大写字母,第 $i+1$ 行表示你的第 $i$ 次操作是从某立柱移到了另一个上。\n\n## 样例 #1\n\n### 样例输入 #1\n\n\n3\n1 2 3\n\n\n### 样例输出 #1\n\n\n5\nA B\nA B\nA C\nB C\nB C\n\n\n## 提示\n\n对于所有数据点:$1\leqslant n \leqslant 4\times 10^4$\n\n| 数据点 | n |\n| :----------: | :----------: |\n| 1~2 | $\leqslant 10$ |\n| 3~4 | $\leqslant 200$ |\n| 5~7 | $\leqslant 3\times 10^4 $ |\n| 8~10 | $\leqslant 4\times 10^4 $ |\n备注:避免运行超时内容:cpp\n#include <iostream>\n#include <vector>\nusing namespace std; \n\nint main() {\n int n;\n cin >> n;\n vector<int> disks(n);\n for (int i = 0; i < n; i++) {\n cin >> disks[i];\n }\n \n vector<pair<char, char>> moves;\n // 将所有圆盘从柱A移动到柱C\n for (int i = 0; i < n; i++) {\n moves.push_back(make_pair('A', 'C'));\n }\n // 将圆盘从柱C移动到柱B,以保持柱A上的顺序\n for (int i = n-1; i > 0; i--) {\n moves.push_back(make_pair('C', 'B'));\n }\n // 将圆盘从柱B移动到柱C,以恢复顺序\n for (int i = 0; i < n-1; i++) {\n moves.push_back(make_pair('B', 'C'));\n }\n \n cout << moves.size() << endl;\n for (int i = 0; i < moves.size(); i++) {\n cout << moves[i].first << " " << moves[i].second << endl;\n }\n \n return 0;\n}\n
原文地址: https://www.cveoy.top/t/topic/pJAN 著作权归作者所有。请勿转载和采集!