题意:
汉诺塔问题,给n个大小不同的碟子及它们的初始位置和目标位置,求出最少的步数,使得每个碟子从初始位置移动到目的位置。
思路:
找出需要移动的最大碟子k, 将1~k 移动到 pos位置(6- start[k] – finish[k] — ( 三个柱子位置1+2+3 – 初始位置 – 目的位置 )—- 即转移需要借用的柱子的位置),同时要让k-1移动到6-start[k]-finish[k]位置,让k-2移动到6-(6-start[k]-finish[k])-finish[k-1],再将1~k-2移动到k-1上,如此递归…
代码:
#include <cstring>
#include <cstdio>
#include <algorithm>
const int N = 65;
int start[N], finish[N], n;
long long ans;
long long f(int *s, int i, int pos) {
if (i == 0)return 0;
if (s[i] == pos) return f(s, i - 1, pos);
return f(s, i - 1, 6 - s[i] - pos) + (1LL << (i - 1));
}
int main() {
int Case=0;
while (~scanf("%d", &n)&& n) {
for (int i = 1; i <= n; i++) scanf("%d", &start[i]);
for (int i = 1; i <= n; i++) scanf("%d", &finish[i]);
int k = n;
while (k >= 1 && start[k] == finish[k]) k--;
ans = 0;
if (k >= 1) {
int pos = 6 - finish[k] - start[k];
ans = f(start, k - 1, pos) + f(finish, k - 1, pos) + 1;
}
printf("Case %d: %lld\n", ++Case, ans);
}
return 0;
}