acwing奇怪的汉诺塔(汉诺四塔问题)

题目链接:https://www.acwing.com/activity/content/problem/content/330/

难度评价:中偏易

题目大意:表面意思

解题思路:转化成经典哈诺三塔实现,并用经典三塔递归公式ans=2^n-1或者是b[n]=2*b[n-1]+1;

先来求解一下三塔问题:https://acm.sdut.edu.cn/onlinejudge3/problems/1200

三塔问题已经再熟悉不过,即是先将第n个盘子移动到B柱,再将剩下的n-1个盘子移动到C柱,最后将剩下的1个盘子移动到C柱;

实现一下代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 int n;
 6 void hanoi(int step,char a,char b,char c)
 7 {
 8     if(step==1)
 9     {
10         printf("Move disk %d from %c to %c\n",step,a,c);
11     }
12     else{
13         hanoi(step-1,a,c,b);//先将n-1盘子从a柱借助c柱子移动到b柱
14         printf("Move disk %d from %c to %c\n",step,a,c);//再将一个盘子从a柱移动到c柱
15         hanoi(step-1,b,a,c);//再将剩下的n-1个盘子借助a柱从b柱移动到c柱
16     }
17 }
18 signed main()
19 {
20     IOS;
21     cin>>n;
22     char a='A',b='B',c='C';
23     hanoi(n,a,b,c);
24     return 0;
25 }

在来说哈诺四塔的问题

我们可以这样来实现,令b[n]表示在n个盘子的情况下求解三塔问题的最小步数,显而易见是b[n]=2*b[n-1]+1;

令a[n]表示n个盘子在四塔问题下的最小求解步数

先将i个盘子在四塔的模式下移动移动到B盘,再将剩下的n-i个盘子在三塔模式下移动到D盘,最后再将第i个盘子在四塔的模式下移动移动到D盘

可以实现这样的递推式:a[n]=min(a[n],a[i]*2+b[n-i]

参考代码:

 1 #include<bits/stdc++.h>//hanoi四塔
 2 using namespace std;
 3 #define int long long
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int n=12;
 6 const int  N=50;
 7 int a[N];//在四塔下的最短步数
 8 int b[N];//在三塔下的最短步数
 9 void hanoi()
10 {
11     b[1]=1;
12     for(int i=2;i<=n;i++)
13     {
14         b[i]=2*b[i-1]+1;
15     }
16     memset(a,0x3f,sizeof(a));
17     a[0]=0;
18     for(int i=1;i<=n;i++)
19     {
20         for(int j=0;j<i;j++)
21         {
22             a[i]=min(a[i],2*a[j]+b[i-j]);
23         }
24     }
25     for(int i=1;i<=n;i++)
26         cout<<a[i]<<endl;
27 }
28 signed main()
29 {
30     IOS;
31     hanoi();
32     return 0;
33 }

 

posted @ 2022-07-12 12:55  江上舟摇  阅读(161)  评论(0编辑  收藏  举报