漢諾塔題目總結

2021-07-02 01:37:57 字數 3651 閱讀 7500

參考了別人的**的總結

1.四柱漢諾塔問題和n柱漢諾塔問題

題目:參考了別人的題解:

#include

#include

#include

using

namespace

std;

double f[70];

void init()

}int main()

return

0;}

2.計算某個盤子被移動的次數

題目:解題思路:第n個盤子移動的步數肯定是1

移動第n個盤子到c柱之後,第n-1個盤子移到c柱子之前,第n -1個盤子移動了1次,然後不考慮第n個盤子,第n-1個盤子還需要移動1次,所以總的移動了2次。

第一次第n-1個盤子到b柱時,第n-2個盤子已經移動了2次。然後將第n-1個盤子看成第n個盤子,第n-2個盤子看成第n-1個盤子,就可以遞推下去了

如果不理解的話,可以動手畫畫,畫一下就知道了

#include

long

long ans[65];

int main()

return

0;}

3.無規則漢諾塔

題目:解題思路:每個盤子都有三種擺放方式,所以共有3^n種

#include

int main()

return

0;}

4.狀態查詢

題目解題思路:按照最優漢諾塔的規則

1. 將a柱上的n-1個盤子放到b柱子上

2. 將a柱子上的第n個盤子移動到c柱子上

3. 最後將b柱子上的n-1個盤子移動到c柱子上

這三個形成遞迴過程,也就是說,第n個盤子所在的位置要麼是在a柱子上,要麼就是在c柱子上,且是將a柱上的n移動到c柱子上了

設乙個函式f(int n,int * a, int *b, int *c)

代表三個柱子,如果第n個盤子在b柱子上,表示false了

如果第n個盤子在a柱子上,下一步就是要把第n-1個盤子從a柱子移動到c柱子上

如果第n個盤子在c柱子上,下一步就是要把b柱子上的第n-1個盤子移動到c柱子上了

#include

#include

#define maxn 70

int num[3][maxn];

bool solve(int n, int

*one, int

*two, int

*three)

int main()

printf("%s\n", solve(n,num[0],num[1],num[2]) ? "true" :"false");

}return

0;}

5.不規則移動

a. 題目:

解題思路:

1.先把a柱子上的n-1個盤子移動到c柱子上

2.再把a柱子上的第n個盤子移動到b柱子上

3.再把c柱子上的n-1個盤子移動到a柱子上(和第一步對稱)

4.把b柱子上的第n個盤子移動到c柱子上

5.最後把a柱子上的n-1個盤子移動到c柱子上

#include

int main()

return

0;}

b.

題目:d陣列紀錄的是將a柱上的n個移動到b柱上需要的步數

可得到遞推公式

d[n] = f[n - 1] + 1 + f[n - 2] + 1 + d[n - 2]

表示先將a柱上的n-1個移動到c柱子上,再將第n個從a柱移動到b柱上,再將c柱子上的n-2個盤子移動到a柱子上,再將第n-1個盤子移動到b柱子上,最後再將a柱子上的n-2個盤子移動到b柱子上

e陣列紀錄的是將b柱子上的盤子移動到c柱子上

可得到遞推公式

e[n] = e[n - 2] + 1 + f[n - 2] + 1 + f[n - 1]

先講b柱子上的n-2個盤子移動到c柱子上,再將第n-1個盤子移動到a柱子上,再將c柱子上的n-2個盤子移動到a柱子上,再將b柱子上的第n個盤子移動到c柱子上,最後減a柱子上的n-1個盤子移動到c柱子上

g陣列紀錄的是符合所有規則的移動次數

得遞推公式

g[n] = f[n-2] + 1 + f[n-3] + 1 + d[n-3] + 2 + e[n-3] + 1 + f[n-3] + 1 + f[n-2]

具體的自己思考了

#include

#include

using

namespace

std;

#define maxn 25

int main()

int test, n;

scanf("%d", &test);

while(test--)

return

0;}

6.計算第n步移動的是哪個盤子

解題思路:

第乙個盤子在第1步的時候會被移動

只有兩個盤子的情況下,第乙個盤子在第一步的時候會被移動,然後在第3步的時候會被移動到,也就是在盤子2移動到c柱子的後的

只有三個盤子的情況下,前面的移動和兩個盤子的移動是一樣的,然後第乙個盤子在第5步的時候會被移動到,然後移動的步驟和兩個的情況下又是一樣的

也就是說第乙個盤子的移動是1,3,5,7…

第二個盤子的移動是2,6,10,14…

第三個盤子的移動是4,12,20…

以此遞迴的

#include

int main() }}

return

0;}

7.每根柱子的狀態

a. 解題思路:先紀錄把n個盤子從a柱子移動到c柱子的所需要步數,如果當前的步數大於把n個盤子從a柱子移動到c柱子的所需步數,就表示可以把n個盤子移動到b柱子,然後把第n+1個盤子移動到c柱子上,就表示第n+1個盤子在c柱子上了,以此遞迴下去

#include

#include

using namespace std;

int main()

else

}for(int i = 0; i < 3; i++)

}return

0;}

b.

解題思路:紀錄要在第幾步才能移動第n個盤子

1.如果當前步驟數等於要移動第n個盤子的步數,就表示剛好把第n個盤子從a柱子移動到c柱子

2.如果當前步驟數大於要移動第n個盤子的步數,就把第n個盤子從a柱子移動到c柱子,再繼續遞迴

3.如果當前步驟數小於要移動第n個盤子的步數,就表示第n個盤子不用移動,接著遞迴,把第n-1個盤子從a柱子移動到b柱子

#include

long

long ans[64];

void move(int n, long

long m, int s, int e)

if(m > tmp)

else

move(n - 1, m, s, mid);

}int main()

return

0;}

經典遞迴題目 漢諾塔

漢諾塔是乙個非常經典的遞迴問題。解決這種遞迴問題,從最簡單的情況開始著手。設現在有三個位置,分別是起始位置,過渡位置,目標位置。假設 n 1,那麼直接一步就可以了。n 2 時,我們需要把起始位置上面的小的一塊先放到 過渡位置,然後把大的一塊放到目標位置。再把小的放到大的上去。n 3 時,可以看到,要...

漢諾塔問題總結

前言今天在看 二叉樹的時候 裡面好多思想都涉及到遞迴,加上我之前一直對遞迴了解的不是很清除,所以打算系統的學一下,這一學不要緊 可把我給整苦了 腦子太笨繞不過來 有一篇部落格說 學遞迴最好最有代表性的演算法問題算是 漢諾塔問題 了 然後就試著了解了一下漢諾塔問題 並留下了 這篇文章作為總結 怕自己忘...

python 漢諾塔 Python漢諾塔

import turtle class stack def init self self.items def isempty self return len self.items 0 def push self,item def pop self return self.items.pop def ...