漢諾塔問題描述:
有三個柱子,其中一個柱子上從下往上放着直徑依次增大的圓盤,要求把這些圓盤移動到另一個圓盤,移動的過程中不能使小的圓盤在大的圓盤下面,問如何移動。
分析:
遞歸的經典問題,不能太拘泥於細節的實現。
首先,來看倒數第二個局面,假設1,2,3柱,最大的圓盤在1柱,1到n-1個圓盤在3柱,現在只需要把1到n-1個圓盤移動到1柱,由於n的直徑大於前n - 1個圓盤,那么1柱實際既可以看成空柱,因為我們不移動第n個,所以它的存在對結果不影響,所以現在就只剩移動n-1個圓盤的工作量。
這就跟移動n個圓盤的問題結構是一樣的,只不過規模減小了1,所以,這就是遞歸的子問題。
我們每一次的移動,就只需要考慮把我們的目標柱子和中轉柱子以及起始柱子的位置互換一下就ok了。
總結:
分析遞歸的問題,一般是尋找與最大的問題結構相同的子問題,然后逐漸減小問題規模,達到最終解決問題的目的。
代碼:
1 #include <stdio.h> 2 3 int cnt = 0; 4 5 void move(char from,char to) 6 { 7 printf("%d %c -> %c\n",++cnt,from,to); 8 } 9 10 void hanota(int n,char from,char trans,char to) 11 { 12 if (n == 1) move(from,to); 13 else 14 { 15 hanota(n-1,from,to,trans); 16 move(from,to); 17 hanota(n-1,trans,from,to); 18 } 19 } 20 21 int main() 22 { 23 int n; 24 25 scanf("%d",&n); 26 27 hanota(n,'A','B','C'); 28 29 printf("Total times : %d\n",cnt); 30 31 return 0; 32 }