栈实现递归

windzhao6 / 2024-09-21 / 原文

汉诺塔

逆序输出(栈先进后出)

#include<iostream>
#include<stack>
#include<tuple>
using namespace std;
int n;
const int N = 10010;
stack <tuple<int, char, char, char>>stk;
void move(char a, char b)
{
   // cout << a << " -> " << b << endl;傻逼会超时
}
void Hanoi(int n, char a, char b, char c)
{
    stk.push(make_tuple(n,a,b,c));
    while (!stk.empty())
    {
        //取
       int cur_n = get<0>(stk.top());
       char cur_a = get<1>(stk.top());
       char cur_b = get<2>(stk.top());
       char cur_c = get<3>(stk.top());
        stk.pop();
        if (cur_n == 1)
        {
            move(cur_a, cur_c);
        }
        else
        {
            //放--递归分解
            stk.push(make_tuple(cur_n - 1, cur_a, cur_c, cur_b));
            stk.push(make_tuple(1, cur_a, cur_b, cur_c));
            stk.push(make_tuple(cur_n - 1, cur_b, cur_a, cur_c));
        }

    }
    /*if (n == 1)move(a, c);
    else
    {
        Hanoi(n - 1, a, c, b);
        move(a, c);
        Hanoi(n - 1, b, a, c);
    }*/
}

int main()
{
    // 关闭输入输出缓存,使效率提升
    ios::sync_with_stdio(false);
    // 解除cin和cout的默认绑定,来降低IO的负担使效率提升
    cin.tie(NULL); cout.tie(NULL);
    cin >> n;
    Hanoi(n, 'a', 'b', 'c');

}

正序输出(改良版)特么的会运行超时
ps:调试不好,已老实

#include <iostream>
#include <stack>
#include <tuple>
#include <vector> // 添加头文件
using namespace std;

int n;
const int N = 10010;
stack<tuple<int, char, char, char>> stk;
vector<string> moves; // 用于记录移动步骤

void move(char a, char b) {
    moves.push_back(string(1, a) + " -> " + string(1, b)); // 记录移动
}

void Hanoi(int n, char a, char b, char c) {
    stk.push(make_tuple(n, a, b, c));
    while (!stk.empty()) {
        // 取
        int cur_n = get<0>(stk.top());
        char cur_a = get<1>(stk.top());
        char cur_b = get<2>(stk.top());
        char cur_c = get<3>(stk.top());
        stk.pop();
        if (cur_n == 1) {
            move(cur_a, cur_c);
        }
        else {
            // 放--递归分解
            stk.push(make_tuple(cur_n - 1, cur_a, cur_c, cur_b));
            stk.push(make_tuple(1, cur_a, cur_b, cur_c));
            stk.push(make_tuple(cur_n - 1, cur_b, cur_a, cur_c));
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n;

    Hanoi(n, 'a', 'b', 'c');

    // 反转并输出所有移动
    for (auto it = moves.rbegin(); it != moves.rend(); ++it) {
        cout << *it << endl;
    }

    return 0;
}

无所谓,直接递归通过

#include <iostream>
using namespace std;

void move(char a, char b) {
    printf("%c -> %c\n", a, b);
  
}

void Hanoi(int n, char a, char b, char c) {
    if (n == 1) {
        move(a, c);
    }
    else {
        Hanoi(n - 1, a, c, b);
        move(a, c);
        Hanoi(n - 1, b, a, c);
    }
}

int main() {
    int n;
    cin >> n;
    Hanoi(n, 'a', 'b', 'c');
    return 0;
}