汉诺塔 X(二分法)

来源:互联网 发布:js实现div逆时针旋转 编辑:程序博客网 时间:2024/06/07 04:36

http://acm.hdu.edu.cn/showproblem.php?pid=2511

汉诺塔 X

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 640    Accepted Submission(s): 383


Problem Description
1,2,...,n表示n个盘子.数字大盘子就大.n个盘子放在第1根柱子上.大盘不能放在小盘上.在第1根柱子上的盘子是a[1],a[2],...,a[n]. a[1]=n,a[2]=n-1,...,a[n]=1.即a[1]是最下面的盘子.把n个盘子移动到第3根柱子.每次只能移动1个盘子,且大盘不能放在小盘上.问第m次移动的是哪一个盘子,从哪根柱子移到哪根柱子.例如:n=3,m=2. 回答是 :2 1 2,即移动的是2号盘,从第1根柱子移动到第2根柱子 。 
 

Input
第1行是整数T,表示有T组数据,下面有T行,每行2个整数n (1 ≤ n ≤ 63) ,m≤ 2^n-1 
 

Output
输出第m次移动的盘子号数和柱子的号数.
 

Sample Input
43 24 539 18325193794263 3074457345618258570
 

Sample Output
2 1 21 3 12 2 32 2 3
 

听说这一题是二分,所以在网上搜索了一下答案,发现有一个没有写注释的就拿来用了下。注意本题中给定一个n,中间那个移动的一定是最底下的那个盘子,因此二分判断

#include <cstdio>__int64 s[70];int flag;void fun(char a,char b,char c,int n,__int64 m){    if(flag)return;    if(m>s[n])        fun(b,a,c,n-1,m-s[n]);//先将a号盘子的前n-1个盘子全移到b上,在将n号盘子移到c,将ba调换位置    else if(m==s[n]){flag=1;printf("%d %c %c\n",n,a,c);}    else fun(a,c,b,n-1,m);//在n-1个盘子中是哪个从哪移到哪}int main(){    s[1]=1;    for(int i=2;i<=64;i++)        s[i]=s[i-1]*2;    int t;    scanf("%d",&t);    while(t--){        __int64 n,m;        scanf("%I64d%I64d",&n,&m);        flag=0;        fun('1','2','3',n,m);//fun的功能是在n个盘子下第m次是哪个盘子从哪移到哪;    }    return 0;}


0 0
原创粉丝点击