PTA 漢諾塔的非遞歸實現(C 語言)


借助堆棧以非遞歸(循環)方式求解漢諾塔的問題(n, a, b, c),

即將N個盤子從起始柱(標記為“a”)通過借助柱(標記為“b”)移動到目標柱(標記為“c”),

並保證每個移動符合漢諾塔問題的要求。

輸入格式:

輸入為一個正整數N,即起始柱上的盤數。

輸出格式:

每個操作(移動)占一行,按柱1 -> 柱2的格式輸出。

輸入樣例:

3

輸出樣例:

a -> c a -> b c -> b a -> c b -> a b -> c a -> c

 

遞歸思路:

(1)先將 n - 1 個盤子從 a 通過 c 移動到 b 。

(2)再將最后一個盤子從 a 移動到 c 。

(3)最后將 n - 1 個盤子從 b 通過 a 移動到 c 。

遞歸代碼:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
void move(int n,char a, char b,char c) {
    if (n == 1) {
        printf("%c -> %c\n", a, c);
        return;
    }
    move(n - 1, a, c, b);
    printf("%c -> %c\n", a, c);
    move(n - 1, b, a, c);
}
int main() {
    int n; scanf("%d", &n);
    move(n, 'a', 'b', 'c');
    system("pause");
}

 

 

非遞歸思路:

(1)將最小圓盤移動到下一個柱子上

(2)對剩余兩柱子進行頂上最小的元素判斷,把小一點的圓盤移動到大一點的圓盤上(有空柱則摞在空柱子上)。

 重復上述兩步就可以得到答案。

注意:這樣得到的最后的答案不一定是摞在 c 上,如果 N 是奇數將摞在 b 上,所以如果 N 是奇數我們就令第二個柱子為 c ,第三個柱子為 b ,這樣就一定最后是摞在 c 上的。

非遞歸代碼:

#define _CRT_SECURE_NO_WARNINGS//C++ 中使用 scanf 和 printf 會報錯 #include <iostream> #include <stack>
using namespace std; stack<int> s[3]; char name[3] = { 'a','b','c' }; void movemin(int a, int b) {//移動剩余兩柱子操作
//a 柱為空或 a 柱頂部圓盤大於 b 柱頂部圓盤,則將 b 柱頂部圓盤移動到 a 柱
if (s[a].empty() && !s[b].empty() || (!s[a].empty() && !s[b].empty() && s[a].top() > s[b].top())) { s[a].push(s[b].top()); s[b].pop(); printf("%c -> %c\n", name[b], name[a]); return; }
//圓盤由 a 柱移動到 b 柱
if (s[b].empty() && !s[a].empty() || (!s[a].empty() && !s[b].empty() && s[a].top() < s[b].top())) { s[b].push(s[a].top()); s[a].pop(); printf("%c -> %c\n", name[a], name[b]); return; } } int main() { int n; scanf("%d", &n);for (int i = n; i >= 1; i--) s[0].push(i); int now = 0; int before, after = 1; if (n % 2 == 1) {//n 為奇數 name[1] = 'c'; name[2] = 'b'; } while (true) {
//now 為最小圓盤所在柱 movemin(after, now);//(1)操作
if (s[after].size() == n) break; before = now; now = after; after = (now + 1) % 3; movemin(before, after);//(2)操作 } system("pause"); }

注意:使用 cin 和 cout 會超時,故使用 scanf 和 printf 輸入輸出。 

(— 3— 好嘛,檢查了半天錯誤,以為是方法不對,結果發現 < 寫成 > 了。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM