SPOJ HAN01(典型汉诺塔)

来源:互联网 发布:rpc调用 vscode 插件 编辑:程序博客网 时间:2024/06/07 13:22

暑期个人赛第二场 Problem A

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

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

代码入下:

#include <cstdio>#define M 64long 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;}


原创粉丝点击