ACM Hanoi双塔问题(C++和python)

1.题目

        给定A、B、C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的。
现要将这些圆盘移到C柱上,在移动过程中可放在B柱上暂存。要求:每次只能移动一个圆盘;A、B、C三根细柱上的圆盘都要保持上小下大的顺序;

- Input:每组输入数据为一个正整数n,表示在A柱上放有2n个圆盘。数据规模:对于50%的数据,1<=n<=25;对于100%的数据,1<=n<=200;
- Output:每组输出仅一行,包含一个正整数,为完成上述任务所需的最少移动次数。

2.解题思路

        我们做一个比较简单的递推,要把2N个盘从A移动到B上,就先移动2(N-1)个到C上,在移2个到B上。

        再把2(N-1)个移到B上,因此F(N)=2*F(N-1)+2

        F(1)=2,易得F(N)=2^(N+1)-2

解题思路比我想法更好,描述更清晰的文章很多啊。这里上链接

这篇分析的不错:

【NOIP2007普及组】Hanoi双塔问题 - 腾讯云开发者社区-腾讯云

以下这篇是我见到的分析最好的:

https://www.iteye.com/blog/shmilyaw-hotmail-com-2077098

3. 编程

3.1 使用C++语言

程序

#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
string gaojing(string ,string );
int main()
{
    int n;
    printf("Please enter a number:");
    cin>>n;
    string a="2";
    string b="2";
    for(int i=2;i<=n;++i)
        a=gaojing(gaojing(a,a),b);
    printf("The least time to complete task:");
    cout<<a;
    return 0;
}
string gaojing(string a,string b)
{
    int js[200];
    int a1[200]={0};
    int a2[200]={0};
    int x=0;
    int y=0;
    string liehuo;
    for(int i=a.size()-1;i>=0;--i)
    {
        x++;
        a1[x]=a[i]-48;
    }
    for(int j=b.size()-1;j>=0;--j)
    {
        y++;
        a2[y]=b[j]-48;
    }
    int max=x>y? x:y;
    for(int i=1;i<=max+1;++i)
    {
        js[i]=(a1[i]+a2[i])%10;
        a1[i+1]+=(a1[i]+a2[i])/10;
    }
    for(int i=max+1;i>=1;--i)
    {
        if(i==max+1&&js[i]==0)
            continue;
        liehuo+=js[i]+48;
    }
    return liehuo;
}

测试

C:\Users\zhangyy\CLionProjects\Ctest\cmake-build-debug\Ctest.exe
Please enter a number:8
The least time to complete task:510
Process finished with exit code 0

3.2 使用python语言

既然我们已经推导出公式那就直接套公式。

程序

print("please input a number:")
a = int(input())
print("The least time to complete task is:")
print(2 ** (a + 1) - 2)

测试

C:\Users\zhangyy\PycharmProjects\ACM_Test\venv\Scripts\python.exe C:\Users\zhangyy\PycharmProjects\ACM_Test\main.py 
please input a number:
8
The least time to complete task is:
510

Process finished with exit code 0

4.最后

        Hanoi塔问题是一个经典的递归问题,它本身的数学复杂度达到了指数函数级别。所以使得运算时间的增长非常快。通过一种递归的思路,首先我们可以总结出一个问题的递归描述方式。然后我们再通过不断的代入和分析,去发现形成等式的规律。这是一种发现递归问题等式描述的方法。为了保证方法最终的正确性,我们还需要经常使用数学归纳法来证明这个等式的正确性。

猜你喜欢

转载自blog.csdn.net/qq_33163046/article/details/128262267