UVA - 10795 A Different Task

来源:互联网 发布:知乎怎么查找专栏 编辑:程序博客网 时间:2024/04/30 21:43

题意:给定一个初始状态和目标状,求从初始状态到目标状态最少要多少步,规则跟汗诺塔是一样的

思路:看了大白的是:先找到需要移动的最大的K,比它大的显然是不需要移动的可以不用考虑,那么可以考虑在将第K个盘子移动的前一步的状态一定是:K在第一根柱子,比大小的依次排在第3根柱子,将这个状态定位参考状态,那么初始状态到这个参考状态加上目标状态到参考状态的步数再+1就是答案了,那么在移动的过程中,如果当前需要移动的N在目标状态那么就不需要移动,就是等于前N-1的步数,否则就是要把前N-1个先移动到另一根暂放,而这个过程满足经典的汉诺塔问题,步数就是2^(N-1)-1,还要再加上移动第N个的1

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 70;int n,start[MAXN],finish[MAXN];long long f(int *p,int i,int final){    if (i == 0)            return 0;    if (p[i] == final)        return f(p,i-1,final);    return f(p,i-1,6-p[i]-final) + (1LL<<(i-1));}int main(){    int cas = 0;    while (scanf("%d",&n) != EOF){        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--;        long long ans = 0;        if (k >= 1){            int other = 6 - start[k] - finish[k];            ans = f(start,k-1,other) + f(finish,k-1,other) + 1;        }        printf("Case %d: %lld\n",++cas,ans);    }    return 0;}



原创粉丝点击