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;
}
浙公网安备 33010602011771号