SPOJ HAN01(典型汉诺塔)

暑期个人赛第二场 Problem A

题意:给一挪动次数,要求写出此时的汉诺塔上的状态.

思路:汉诺塔的典型利用,用递归实现即可。

代码入下:

#include <cstdio>
#define M 64
long long n, k;
int ai, bi, ci, a[M], b[M], c[M];
void f(int i, int x)
{
    if(i==1) a[ai++] = x;
    if(i==2) b[bi++] = x;
    if(i==3) c[ci++] = x;
}
long long pow(int x, int o)
{
    if(o==0) return 1;
    long long ans = pow(x,o/2);
    if(o%2)
        return ans*ans*x;
    return ans*ans;
}
void hanoi(long long n, int x, int y, int z, long long k)
{
    if(k==0)
    {
        for(int i = n; i >= 1; i--)
            f(x,i);
        return;
    }
    if(n==0) return;
    long long mid = pow(2,n-1)-1;
    if(k<mid) { f(x, n); hanoi(n-1,x,z,y,k); }//正在做前n-1个盘子的x->y挪动
    if(k==mid) { f(x,n); hanoi(n-1,z,y,x,k-mid);}//刚好完成挪动
    if(k>mid) { f(y, n); hanoi(n-1,z,y,x,k-mid-1);}//已经把最下面的盘子挪到了y上
}
int main ()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld %lld",&n,&k);
        ai = bi = ci = 0;
        hanoi(n,1,2,3,k);
        printf("1: ");
        for(int i = 0; i < ai; i++)
            {if(i) printf("|"); printf("%d",a[i]);}
        printf("\n");
        printf("2: ");
        for(int i = 0; i < bi; i++)
            {if(i) printf("|"); printf("%d",b[i]);}
        printf("\n");
        printf("3: ");
        for(int i = 0; i < ci; i++)
            {if(i) printf("|"); printf("%d",c[i]);}
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(SPOJ HAN01(典型汉诺塔))