汉诺塔之递推

参考博客:http://blog.csdn.net/u014135021/article/details/50995386

汉诺塔的递推核心代码为

a[1]=1;
for(int i=2;i<=n;i++)
    a[i]=2*a[I-1]+1;
由递归算法可知,我们要想把A塔上n个盘子挪到C盘
1先把n-1个盘子挪到B盘
2把第n个盘子挪到C盘
3n-1个盘子挪到c盘
1和3步骤近似相同,只是借助的塔不一样。我们不妨开一个数组a,a[I]表示移动I个盘子所需要步数,我们可知第一步对应的步数为a[n-1],所以得到上面的递推公式

汉诺塔IX

                      HDU - 2175                                                     
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次移动的是那一个盘子. 

Input每行2个整数n (1 ≤ n ≤ 63) ,m≤ 2^n-1.n=m=0退出Output输出第m次移动的盘子的号数.Sample Input

63 1
63 2
0 0

Sample Output

1
2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
long long n, m;
long long a[65], b[65];
void init()
{
    a[1] = 1;
    b[1] = 2;
    b[0] = 1;
    for(int i = 2; i <= 63; i ++)
    {
        a[i] = a[i - 1]*2 + 1;
        b[i] = a[i] + 1;
    }
}
int  sove()
{
    if(m == a[63])
        return 1;
    while(m > 0)
    {
        int t = 0;
        while(m > b[t])
        {
            t ++;
        }
        if(m == b[t])
            return t + 1;
        m -= b[t - 1];
    }
}

int main()
{
    init();
    while(scanf("%lld %lld", &n, &m) != EOF)
    {
        if(n == 0&&m == 0)
            break;
        printf("%d\n", sove());
    }

    return 0;
}

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/sdnulixianrui/article/details/79271137
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞