zoukankan      html  css  js  c++  java
  • 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
    ", a, c);
            return;
        }
        move(n - 1, a, c, b);
        printf("%c -> %c
    ", 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 ", 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 ", 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— 好嘛,检查了半天错误,以为是方法不对,结果发现 < 写成 > 了。)

  • 相关阅读:
    跳槽面试技巧记录
    看了多篇2019年的面经后的个人总结
    TypeScript躬行记(8)——装饰器
    TypeScript躬行记(7)——命名空间
    TypeScript躬行记(6)——高级类型
    TypeScript躬行记(5)——类型兼容性
    TypeScript躬行记(4)——泛型
    TypeScript躬行记(3)——类
    TypeScript躬行记(2)——接口
    Error, some other host already uses address 192.168.0.202错误解决方法
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/11740649.html
Copyright © 2011-2022 走看看