zoukankan      html  css  js  c++  java
  • hdu 2511 汉诺塔 X

    汉诺塔 X

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


    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
    4
    3 2
    4 5
    39
    183251937942
    63 3074457345618258570
     
    Sample Output
    2 1 2
    1 3 1
    2 2 3
    2 2 3
    //这个结论推了一个多小时才推出来、

    #include <iostream>
    #include <cmath>
    #include <stdio.h>
    using namespace std;
    __int64 m;
    void recursion(int a,int b,int c,__int64 n)
    {
        __int64 t=pow(double(2),double(n-1));
        int i=0;
        while(t>m)
        { t=t>>1;i++;}
        m=(t^m);
        if(m==0)
        {
            int k=1;
            while(t%2==0) k++,t=t>>1;//这个依靠上题的规律
            if(i%2)
              printf("%d %d %d\n",k,a,b);
            else
              printf("%d %d %d\n",k,a,c);
            return ;
        }
        if(i%2)//判断与底层的关系
         recursion(c,a,b,n-i-1);
        else
         recursion(b,a,c,n-i-1);
    }
    int main()
    {
        __int64 k;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%I64d%I64d",&k,&m);
            recursion(1,2,3,k);
        }
        return 0;
    }

  • 相关阅读:
    Android xml text 预览属性
    GridView、ListView默认的点击背景修改
    java.util.ConcurrentModificationException
    Android 菜单定制使用小结
    Panel 中加载窗体
    git代理配置
    TableLayoutPanel 动态添加 行 列
    C# 左右补零
    Dart Map<> 添加 元素
    Mac 永久添加 环境变量方法
  • 原文地址:https://www.cnblogs.com/372465774y/p/2603421.html
Copyright © 2011-2022 走看看