汉诺塔问题

/*****************************************************************************************
 *description:汉诺塔问题
 *            n代表汉诺塔游戏中从小到小到大放置的的n个盘子,
 *            开始时,所有盘子都放置在左边的柱子上,按游戏要求将其全部移动至右边,
 *            打印最优移动轨迹。
 *            n个盘子共需要移动2^i-1次

 ****************************************************************************************/

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//方法:
//     step1:把圆盘1~(n-1)从from移动到mid
//     step2:把圆盘n从from移动到to
//     step3:把圆盘1~(n-1)从mid移动到to
void process_1(int n, string from, string mid, string to)
{
    if (n == 1)
        cout << from << " ---> " << to << endl;
    else
    {
        process_1(n-1, from, to, mid);
        process_1(1, from, mid, to);
        process_1(n-1, mid, from, to);
    }
}
void printTrack(int n)
{
    if (n == 0)
        return;
    process_1(3, "left", "mid", "right");
}
int main_06_1()
{
    printTrack(3);
    return 0;
}


/*****************************************************************
 *description:汉诺塔进阶问题
 *            给定数组arr,只含1、2、3,代表圆盘状态,如arr[i]=1,表示i圆盘在左柱
 *            如果arr是汉诺塔最优轨迹上的状态,则返回是第几个状态,否则返回-1
 *****************************************************************/

//方法1:时间复杂度O(N),空间复杂度O(N)
//   对圆盘1~i来说,目标为从from到to,分三种情况:
//      1.圆盘i在from上,不能判定步骤1是否完成,需进一步考虑1~(i-1)的情况,目标为from到mid
//      2.圆盘i在to上,步骤1和2已经完成,已完成2^(i-1)步,再考虑1~(i-1),目标从mid到to
//      3.圆盘i在mid上,最优轨迹不存在这种情况,返回-1
int process_2(vector<int> arr, int i, int from, int mid, int to)
{
    if (i == -1)
        return 0;
    if (arr[i] != from && arr[i] != to)
        return -1;
    if (arr[i] == from)
        return process_2(arr, i-1, from, to, mid);
    else
    {
        int rest = process_2(arr, i-1, mid, from, to);
        if (rest == -1)
            return -1;
        return (1 << i) + rest;
    }

}
int HanoState_1(vector<int> arr)
{
    if (arr.size() == 0)
        return -1;
    return process_2(arr, arr.size()-1, 1, 2, 3);
}

//方法2:时间复杂度O(N),空间复杂度O(1)
//方法1改写为非递归形式。
int HanoState_2(vector<int> arr)
{
    if (arr.size() == 0)
        return -1;
    int from = 1;
    int mid = 2;
    int to = 3;
    int i = arr.size() - 1;
    int res = 0;
    int tmp = 0;
    while(i >= 0)
    {
        if (arr[i] != from && arr[i] != to)
            return -1;
        if (arr[i] == to)
        {
            res += 1 << i;
            tmp = from;
            from = mid;
        }
        else
        {
            tmp = to;
            to = mid;
        }
        mid = tmp;
        i--;
    }
    return res;
}

int main_06_2()
{
    vector<int> arr;
    arr.push_back(2);
    arr.push_back(1);
    cout << HanoState_2(arr);
    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值