參考了別人的**的總結
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 ...