基础算法 —— 递归/递推 —— 汉诺塔问题(Hanoi)
生活随笔
收集整理的這篇文章主要介紹了
基础算法 —— 递归/递推 —— 汉诺塔问题(Hanoi)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【問題提出】
Hanoi塔由n個大小不同的圓盤和三根木柱a,b,c組成。開始時,這n個圓盤由大到小依次套在a柱上,如圖所示。?
要求把a柱上n個圓盤按下述規則移到c柱上:?
(1)一次只能移一個圓盤;?
(2)圓盤只能在三個柱上存放;?
(3)在移動過程中,不允許大盤壓小盤。?
問將這n個盤子從a柱移動到c柱上,總計需要移動多少個盤次??
【問題解答】
解:設Hn為n個盤子從a柱移到c柱所需移動的盤次。
????顯然,當n=1時,只需把a 柱上的盤子直接移動到c柱就可以了,故:H1=1。
????當n=2時,先將a柱上面的小盤子移動到b柱上去,然后將大盤子從a柱移到c柱,最后,將b柱上的小盤子移到c柱上,共記3個盤次,故:H2=3。
????以此類推,當a柱上有n(n>=2)個盤子時,總是先借助c柱把上面的n-1個盤子移動到b柱上,然后把a柱最下面的盤子移動到c柱上,再借助a柱把b柱上的n-1個盤子移動到c柱上,總共移動H(n-1)+1+H(n-1)個盤次。?
????∴Hn=2H(n-1)+1,邊界條件:H1=1
【遞推實現】
#include<stdio.h> int ct=1;//記錄步數,在步驟中輸出 void move(int n,char from,char to) {printf("第 %2d 步:把第 %d 個盤子: %c >>>>>>> %c\n",ct++,n,from,to); } int hanoi(int n)//輸出步數: {int cnt = 2,ans = 1;if(n == 1)return 1;elsereturn 2* hanoi(n-1) +1; } void hanoi_tower(int n,char x,char y, char z) //輸出步驟 {if(n==1)move(1,x,z);else{hanoi_tower(n-1,x,z,y);move(n,x,z);hanoi_tower(n-1,y,x,z);} } int main() {int n;//盤子個數printf("輸入盤子個數:\n");scanf("%d",&n);char x = 'A',y = 'B',z = 'C';int t = hanoi(n);printf("一共需要%2d步。\n",t);hanoi_tower(n,x,y,z);return 0; }【遞歸實現】
#include<stdio.h> void move(int n, char x, char y, char z)//將n個圓盤從x柱子上借助y柱子移動到z柱子上 {if(n == 1)printf("圓盤編號 %d :從 %c 移動到 %c\n",n,x,z);else{move(n-1,x,y,z);printf("圓盤編號 %d:從 %c 移動到 %c\n",n,x,z);move(n-1,y,x,z);}} int main() {int n;//n代表圓盤的個數/*A,B,C分別代表三個柱子*/char ch1 = 'A';char ch2 = 'B';char ch3 = 'C';printf("請輸入圓盤的個數:");scanf("%d",&n);move(n,ch1,ch2,ch3);return 0; }?
總結
以上是生活随笔為你收集整理的基础算法 —— 递归/递推 —— 汉诺塔问题(Hanoi)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 车厢调度(信息学奥赛一本通-T1357)
- 下一篇: 循环比赛日程表(信息学奥赛一本通-T13