暑期个人赛第二场 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; }