栈解决汉诺塔问题

汉诺塔问题比较经典,这里修改--下游戏规则:

  • 现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。
  • 求当塔有N层的时候,打印最优移动过程和最优移动总步数。
  • 在走出最少步数过程中的任何时刻,四个动作中只有一个动作不违反小压大和相邻不可逆原则(相邻的两次操作不互为逆操作如:MtoR和RtoM),另外三个动作一定都会违反。
#include <iostream>
#include <stack>
using namespace std;

enum Act {                //    利用绝对值解决逆操作问题 感谢Stan提供的思路
    No = 0,
    LtoM = 1,
    MtoL = -1,
    RtoM = 2,
    MtoR = -2
};

int move(Act& reAct, Act nowAct, stack<int>& src, stack<int>& dst) {
    if (!src.empty() && (abs(reAct) != abs(nowAct)) && (dst.empty() || src.top() < dst.top())) {
        dst.push(src.top());
        src.pop();
        switch (nowAct){
        case 1:
            cout << "Move " << dst.top() << " from L to M" << endl;
            break;
        case -1:
            cout << "Move " << dst.top() << " from M to L" << endl;
            break;
        case 2:
            cout << "Move " << dst.top() << " from R to M" << endl;
            break;
        case -2:
            cout << "Move " << dst.top() << " from M to R" << endl;
            break;
        }
        reAct = nowAct;
        return 1;
    }
    return 0;
}

int solveHanoi(int l) {                        //    解决从左往右移动的问题
    stack<int> lS, mS, rS;
    for (int i = l; i > 0; i--)                //    修改此处可决定源栈
    {
        lS.push(i);
    }
    Act record = No;
    int step = 0;
    while (rS.size() != l)                    //    修改此处可决定目的栈
    {
        step += move(record, LtoM, lS, mS);
        step += move(record, MtoL, mS, lS);
        step += move(record, RtoM, rS, mS);
        step += move(record, MtoR, mS, rS);
    }
    return step;
}

int main()
{
    cout << "Solve 3 Hanoi LtoR:" << endl;
    cout << "I will move " << solveHanoi(3) << " steps" << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/MuZiShiYe/p/11270104.html

时间: 2024-10-09 20:19:55

栈解决汉诺塔问题的相关文章

【算法题】06-用栈来解决汉诺塔问题

用栈来解决汉诺塔问题 题目 修改汉诺塔问题的游戏规则:限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动和最优移动总步数. 要求: 方法一:递归的方法 方法二:非递归的方法,用栈来模拟汉诺塔的三个塔 思路 方法一:递归的方法 首先,如果只剩最上层的塔需要移动,则有如下处理: 如果希望从左移动到右,打印Move 1 from left to right 如果希望从中移动到左,打印Move 1 from mid to left 如

编程:递归编程解决汉诺塔问题(用java实现)

//Li Cuiyun,October 14,2016.//用递归方法编程解决汉诺塔问题package tutorial_3_5;import java.util.*; public class HanoiTower { public static void main(String[] args) { // TODO Auto-generated method stub @SuppressWarnings("resource") Scanner sc=new Scanner(Syste

【Python学习】Python解决汉诺塔问题

参考文章:http://www.cnblogs.com/dmego/p/5965835.html 一句话:学程序不是目的,理解就好:写代码也不是必然,省事最好:拿也好,查也好,解决问题就好! 信息时代不用信息就是罪过,直接抄不加理解与应用,就不是自己的,下次遇到还是不会,或许其中的某一个细节就能够用于各个问题的解决,共勉 学习一个东西总会遇到一些经典的问题,学习Python第二天尝试看一下汉诺塔问题,还是百度,看看解题思路,纯粹是重温初中课堂,越活越回去了 汉诺塔的图解递归算法 一.起源: 汉诺

用栈模拟汉诺塔问题

在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如,任意一个盘子,其必须堆在比它大的盘子上面).同时,你必须满足以下限制条件: (1) 每次只能移动一个盘子.(2) 每个盘子从堆的顶部被移动后,只能置放于下一个堆中.(3) 每个盘子只能放在比它大的盘子上面. 请写一段程序,实现将第一个堆的盘子移动到最后一个堆中. 分析: (1)n == 1   第1次  1号盘  A---->C       sum = 1 次 (2)  n

lintcode:227.用栈模拟汉诺塔问题

在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如,任意一个盘子,其必须堆在比它大的盘子上面).同时,你必须满足以下限制条件: (1) 每次只能移动一个盘子. (2) 每个盘子从堆的顶部被移动后,只能置放于下一个堆中. (3) 每个盘子只能放在比它大的盘子上面. 请写一段程序,实现将第一个堆的盘子移动到最后一个堆中. 具体思路在本笔记后面有记录! 以下为本人C++版详细过程!包括测试过程 1 class Tower { 2

C#递归解决汉诺塔问题(Hanoi)

using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExample_Hanoi_{    class Program    {        static void Main(string[] args)        {            HanoiCalculator c = new HanoiCalculator();            Cons

递归解决汉诺塔问题

汉诺塔问题:有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,要把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,求至少需要多少次移动. 我们首先假设n=1,那么move(n)=1,因为这时候只需要从A->C便可以.接下来假设n=2,那么move(n)=3 即A->B,A->C,B->C; 假设n=3,move(n)=7 即A->C,A->b,C->B,A->C,B->A,B-

用递归的方法解决汉诺塔问题

1. A->C->B; 2.B->A-C;

汉诺塔的递归算法与解析

从左到右 A  B  C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号. 小时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐心玩了,并且操作的动作都几乎相同觉得无聊.  后来学习编程, 认识到递归, 用递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第一种算法. 至于递归,简单来说