题目链接:uva 10795 - A Different Task
题目大意:就是普通的汉诺塔问题,给出n,表示说有n个大小不同的碟子,然后再给出每个碟子的初始位置和目标位置,要求计算出最少的步数使得每个碟子都移动到它的目标位置。
解题思路:找到需要移动的最大碟子i,然后1~i-1个碟子需要移动到6 - now[i] - end[i],同样的需要让i - 1移动到6 - now[i] - end[i],需要让1~i - 2都移动到 6 - (6 - now[i] - end[i])- now[i - 1],所以很明显是递归求解,注意要将1~i - 2移动到i - 1上面。
然后进行完上述操作,从1~i-1都在同一个柱子上,可以从大到小将每个碟子还原到目标位置。
#include <stdio.h>
#include <string.h>
#include <math.h>
#define ll long long
const int N = 100;
ll T[N];
int n, tmp, now[N], end[N];
void init() {
memset(T, 0, sizeof(T));
T[0] = 1;
for (int i = 1; i <= 63; i++)
T[i] = T[i - 1] * 2;
}
void input() {
memset(now, 0, sizeof(now));
memset(end, 0, sizeof(end));
for (int i = 1; i <= n; i++) scanf("%d", &now[i]);
for (int i = 1; i <= n; i++) scanf("%d", &end[i]);
}
ll move(int d, int aid) {
if (d == 0) return 0;
if (now[d] == aid)
return move(d - 1, aid);
else
return move(d - 1, 6 - now[d] - aid) + T[d - 1];
}
ll solve() {
int i;
ll ans = 0;
for (i = n; i; i--) {
if (now[i] != end[i]) {
tmp = 6 - now[i] - end[i];
ans += move(i - 1, tmp) + 1;
i--;
break;
}
}
for (; i; i--) {
if (end[i] != tmp) {
tmp = 6 - end[i] - tmp;
ans += T[i - 1];
}
}
return ans;
}
int main () {
int cas = 1;
init();
while (scanf("%d", &n) == 1 && n) {
input();
printf("Case %d: %lld\n", cas++, solve() );
}
return 0;
}