@P1242 新汉诺塔
题目描述
设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。
现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。
移动时有如下要求:
·一次只能移一个盘;
·不允许把大盘移到小盘上面。
输入输出格式
输入格式:
文件第一行是状态中圆盘总数;
第二到第四行分别是初始状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号;
第五到第七行分别是目标状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号。
输出格式:
每行一步移动方案,格式为:move I from P to Q
最后一行输出最少的步数。
输入输出样例
输入样例#1: 复制
5 3 3 2 1 2 5 4 0 1 2 3 5 4 3 1 1
输出样例#1: 复制
move 1 from A to B move 2 from A to C move 1 from B to C move 3 from A to B move 1 from C to B move 2 from C to A move 1 from B to C 7
说明
圆盘总数≤45
#include <bits/stdc++.h> using namespace std; #define maxn 100000 typedef long long ll; #define inf 2147483647 #define ri register int int ans = 0; int f1[50], f2[50]; int x, t; int n; void dfs(int d, int x, int y, bool k) { int z = 1; while (x == z || y == z) z++; if (x == y) { if (d > 1) dfs(d - 1, f1[d - 1], k ? f2[d - 1] : y, k); return; } if (d > 1) dfs(d - 1, f1[d - 1], z, false); cout << "move " << d << " from " << char(x + 'A' - 1) << " to " << char(y + 'A' - 1) << endl; ans++; f1[d] = y; if (d > 1) dfs(d - 1, f1[d - 1], k ? f2[d - 1] : y, k); } int main() { ios::sync_with_stdio(false); // freopen("test.txt", "r", stdin); // freopen("outout.txt","w",stdout); cin >> n; cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f1[x] = 1; } cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f1[x] = 2; } cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f1[x] = 3; } cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f2[x] = 1; } cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f2[x] = 2; } cin >> t; for (int i = 1; i <= t; i++) { cin >> x; f2[x] = 3; } dfs(n, f1[n], f2[n], true); cout << ans; return 0; }

浙公网安备 33010602011771号