美文网首页
hanoi塔问题的自己的理解及相关竞赛题的解答

hanoi塔问题的自己的理解及相关竞赛题的解答

作者: 不过意局bugyj | 来源:发表于2018-09-04 14:24 被阅读0次
csdn搬,于2018-01-27 13:38:29发至CSDN

 昨日学习python时一时兴起,决定将hanoi塔问题用python写一遍,然后觉得这个问题实在是太有趣了,搞懂了一个最经典的便可举一反三,以往在比赛中遇到的hanoi问题都可迎刃而解。以下便是总结:(假设从左到右柱子分别为a, b, c)

1、最经典:

当只有一个石块时,只需要从a->c.
两个石块时,第一个石块a->b,然后第二个石块a->c,最后b->c.

后面都是一样的道理,不管多少块,完成都必定经过上面n-1个在b上,然后将最后一个从a->c。最后将n-1个移到c上。n块从a->c需要b的协助,n-1的a->b需要c的协助,便可使用递归!便有以下python代码

def move(*s):
    print(s[0], "移动到", s[1])

def simpleHanoi(n, a, b, c):
    if  n == 1:
        move(a,c)
    else:
        simpleHanoi(n-1,a,c,b)
        move(a,c)
        simpleHanoi(n-1,b,a,c)

simpleHanoi(4, 'A', 'B', 'C')

c++:

#include<iostream>

using namespace std;

void move(char from, char to) {
    cout << from << "移动到" << to << endl;
}

void hanoi(int n, char from, char dependOn, char to) {
    if (n == 1)
        move(from, to);
    else {
        hanoi(n - 1, from, to, dependOn);
        move(from, to);
        hanoi(n - 1, dependOn, from, to);
    }
}

int main(){
    hanoi(5, 'A', 'B', 'C');
    return 0;
}

2、进阶版, 每次只能移到相邻的柱子上:

这个步骤和上面的不太一样,但原理基本相同。基本步骤就是n-1个两步移到c然后最后一个移到b,然后n-1移到

a,最后一个移到c然后n-1移到c大功告成,了解这个就可以写代码了(c++的懒得写了/笑哭):

def move(*s):
    if len(s) == 2:
        print(s[0], "移动到", s[1])
    elif len(s) == 3:
        print(s[0], "移动到", s[1])
        print(s[1], "移动到", s[2])

def hanoi(n = 1, a = 'A', b = 'B', c = 'C'):
    if  n == 1:
        move(a,b,c)
    else:
        hanoi(n-1,a,b,c)
        move(a,b)
        hanoi(n-1,c,b,a)
        move(b,c)
        hanio(n-1,a,b,c)

hanoi(3)
image.gif

3、接着就是各种题目了!

hdu上的2064 汉诺塔III

我本来的代码:

#include<iostream>

using namespace std;

int num;

void hanoi(int n) {
    if (n == 1)
        num += 2;
    else {
        hanoi(n - 1);
        num++;
        hanoi(n - 1);
        num++;
        hanoi(n - 1);
    }
}

int main() {
    int n;
    while (cin >> n && n) {
        num = 0;
        hanoi(n);
        cout << num << endl;
    }
    return 0;
}

可是n<35, 肯定超时啦!

此时假设步骤中移动上面n-1个盘子到c盘要t(n-1)的步数

第n个移动到b1步此时为t(n-1)+1

然后移n-1回a 此时2t(n-1)+1

移中间的第n块要1步即2t(n-1)+ 2

最后完成最后t(n - 1)步

为t(n) = 3*t(n-1) + 2;故而有:

#include<iostream>

using namespace std;

int main() {

    int n;
    while (scanf("%d", &n)!=EOF) {
        long long ans = 2;
        for (int i = 2; i <= n; i++)
            ans = 3 * ans + 2;
        cout << ans << endl;
    }
    return 0;
}

然后就是这道题:N阶汉诺塔变形

要知道这个题目是要实时监控步数的变化的,到步数时就立马收集答案,而步数改变的地方只有move函数,故有上面的代码

更改为:

#include<iostream>
#include<string.h>
#include<stack>

using namespace std;

stack<int> p[4];
stack<int> ans[4];
bool flag;

void moveone(int &k, int from, int to) {
    if (flag)return;
    p[to].push(p[from].top());
    p[from].pop();
    if (k == 1) 
        flag = true;
    else k--;
}

void hanoi(int n, int a, int b, int c, int &k) {
    if (flag || k == 0) {
        for (int i = 1; i <= 3; i++)
            while (!p[i].empty()) {
                ans[i].push(p[i].top());
                p[i].pop();
            }
        return;
    }

    if (n == 1) {
        moveone(k, a, b);
        moveone(k, b, c);
    }
    else {
        hanoi(n - 1, a, b, c, k);
        moveone(k, a, b);
        hanoi(n - 1, c, b, a, k);
        moveone(k, b, c);
        hanoi(n - 1, a, b, c, k);
    }
}

int main() {
    int n, k;
    while (cin >> n >> k&&n) {
        for (int i = 1; i <= 3; i++) {
            while (!p[i].empty())p[i].pop();
            while (!ans[i].empty())ans[i].pop();
        }
        flag = false;
        for (int i = n; i > 0; i--)
            p[1].push(i);
        hanoi(n, 1, 2, 3, k);
        for (int i = 1; i <= 3; i++) {
            if (ans[i].empty())
                cout << 0;
            else while (!ans[i].empty()) {
                cout << ans[i].top()<<" ";
                ans[i].pop();
            }
            cout << endl;
        }
    }
    return 0;
}

代码很复杂,肯定还有更简单的做法!

先写这么多吧!

相关文章

  • hanoi塔问题的自己的理解及相关竞赛题的解答

    从csdn搬,于2018-01-27 13:38:29发至CSDN  昨日学习python时一时兴起,决定将han...

  • 汉诺塔问题与递归

    文章也同时在个人博客 http://kimihe.com/更新 汉诺塔问题(Hanoi Tower) 汉诺塔问题的...

  • Maven相关问题及解答

    文章定位 我写该篇文章是为搜集一些Maven使用中的常见问题并尽可能给出解决方案,每个正在学习Maven的同学都可...

  • 汉诺塔——python

    汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时...

  • 图解 汉诺塔递归算法

    题目: --- (如果看过N次的就不用看了 直接跳到题解) 汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tow...

  • Hanoi塔

    ``` public class Hanoi { public static void moveOne(char ...

  • 分治策略——Hanoi塔问题

    一、单Hanoi塔 上图为 3 阶 Hanoi 塔 假设有三个命名为 A B C 的塔座 ,在塔座A上插有n个直径...

  • C语言-汉诺(Hanoi)塔问题-递归实现

    问题描述:汉诺(Hanoi)塔问题-递归实现 源代码: 运行结果: 程序算法: 程序参数: 输出大小: 149.3...

  • Tower of Hanoi的理解

    汉诺塔之前一直是知道过程,理解不了代码。直到今天在知乎上看到一种理解方式,一下子就懂了。如何理解汉诺塔的递归? -...

  • 《遇见未知的自己》——张德芬

    作者主要通过若菱的各种困境来解答存在的问题及解决办法。但是作者解答的每次问题都很抽象,我无法深层次的理解,只能理解...

网友评论

      本文标题:hanoi塔问题的自己的理解及相关竞赛题的解答

      本文链接:https://www.haomeiwen.com/subject/xedgwftx.html