Hanoi塔問題【遞歸】

(n階Hanoi塔問題)假設有三個分別命名爲A、B、C的塔座,在塔座A上插有n(n<20)個直徑大小各不相同、依小到大編號爲1,2,…,n的圓盤。現要求將A軸上的n個圓盤移至塔座C上並仍按同樣順序疊排,圓盤移動時必須遵循下列規則: 1)每次只能移動一個圓盤; 2)圓盤可以插在A、B、C中的任一塔座上; 3)任何時刻都不能將一個較大的圓盤壓在較小的圓盤之上。 請通過編程來打印出移動的步驟.


Hanoi問題絕對是一個理解遞歸的好題,對一個將N個圓盤從A移動到C的問題,我們可以將它分解成三步

  • 將其上的N-1個圓盤從A移動到B。
  • 將第N個圓盤從A移動到C。
  • 將B上的N-1個圓盤移動到C。

每次移動都有一個起點S,一個終點T,還有一箇中介M,另外還有想要移動的盤子的數目cnt,當需要移動的數目爲1時,我們就可以打印移動的方法。寫成程序就是下面這樣

//將cnt個圓盤從S盤經過M移動到T
void hanoi(char S, char T, char M, ll cnt) {
	if (cnt == 1)
		pprint(S, T);
	else {
		hanoi(S, M, T, cnt - 1);//把上面cnt-1個硬盤從S經過T移動到M
		hanoi(S, T, M, 1);//把最底下的1個硬盤移動到T
		hanoi(M, T, S, cnt - 1);//把移動到M上的cnt-1個硬盤通過S移到終點T
	}
}

然後就是需要注意路徑的打印五個一組,使用一個全局變量進行監控即可

#define ll int
#define inf 0x3ffffff
#define vec vector<ll>

ll tot = 0;

void pprint(char s, char t) {
	if (tot == 5)printf("\n"), tot = 0;
	printf("%c-->%c   ", s, t); tot++;
}
//將cnt個圓盤從S盤經過M移動到T
void hanoi(char S, char T, char M, ll cnt) {
	if (cnt == 1)
		pprint(S, T);
	else {
		hanoi(S, M, T, cnt - 1);//把上面cnt-1個硬盤從S經過T移動到M
		hanoi(S, T, M, 1);//把最底下的1個硬盤移動到T
		hanoi(M, T, S, cnt - 1);//把移動到M上的cnt-1個硬盤通過S移到終點T
	}
}

int main() {
	ll n;
	while (cin >> n && n) {
		hanoi('A', 'C', 'B', n);
		printf("\n"); tot = 0;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章