雙重河內塔I

幽靈軒發表於2020-11-10

雙重河內塔問題

又稱:雙重漢諾塔問題

這是《具體數學:電腦科學基礎(第2版)》中的一道課後習題
這道題也是挺有意義的,我打算寫三篇隨筆來講這個問題,這是第一篇

雙重河內塔包含 2n 個圓盤,它們有 n 種不同的尺寸,每一種尺寸的圓盤有兩個。如通常那樣,要求每次只能移動一個圓盤,且不能把較大的圓盤放在較小的圓盤上面。

a 如果相同尺寸的圓盤是相互不可區分的,要把一個雙重塔從一根樁柱移動到另一根樁柱需要移動多少次?

b 如果在最後的排列中要把所有同樣尺寸的圓盤恢復成原來的從上到下的次序,需要移動多少次?
提示:這是一個難題,實在應該是個“附加題”。

本文章針對a問題,後面兩篇隨筆針對b問題

經典漢諾塔問題如果理解了,a問題應該不難
經典漢諾塔有n個圓盤,我們設將所有圓盤從A塔-->C塔需要的步數為\(F_n\)
\(F_1=1\)
\(F_n = F_{n-1} +1+ F_{n-1}\)
易證\(F_n =2^n -1\)
我們設雙重漢諾塔問題中2n個圓盤,完成所有移動的最終步數為\(A_n\)
易證\(A_n=2 \times F_n\)
\(A_n=2^{n+1}-2\)

程式碼實現

#include<stdio.h>
int step;
void Move(int id,char from,char to){
	printf("第%d步:將%d號型盤子%c-->%c\n",++step,id,from,to);
	return ;
}
void Hanio(int n,char spos,char tpos,char epos){
	if(n==1){
		Move(n,spos,epos);
		Move(n,spos,epos);
	}
	else {
		Hanio(n-1,spos,epos,tpos);
		Move(n,spos,epos);
		Move(n,spos,epos);
		Hanio(n-1,tpos,spos,epos);
	}
}
int main(){
	int n;
	scanf("%d",&n);
	Hanio(n,'A','B','C');
	printf("最後總的步數為%d步\n",step);
}

相關文章