哈喽,大家好,我是Tony:
欢迎大家访问我的个人主页:Tony’s Blog,让我们一起站在巨人的肩膀之上!
这篇博客将以《汉诺塔》为基础进行汉诺塔进阶:
编程题
给定一个整形数组arr,其中只含有1,2和3,代表所有圆盘目前的状态,1代表左柱,2代表中柱,3代表右柱,arr[i]的值代表第i+1个圆盘的位置。比如,arr=[3,3,2,1],代表第一个圆盘在右柱上、第2个圆盘在右柱上、第3个圆盘在中柱、第4个圆盘在左柱上。如果arr代表的状态是最优移动轨迹过程中出现的状态,返回arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的状态不是最优移动轨迹过程中出现的状态,则返回-1.
举例
arr[1,1]。两个圆盘目前都在左柱上,也就是初始状态,所以返回0.
arr[2,1]。第一个圆盘在中柱上,第二个圆盘在左柱上,这个状态是2个圆盘的汉若塔游戏最优移动轨迹的第1步,所以返回1
arr[3,3]。第一个圆盘在右柱上,第2个圆盘在右柱山个,这个状态是2个圆盘的汉诺塔游戏中最优移动轨迹的第3步,所以返回3.
arr[2,2]。第一个圆盘在中柱上、第二个圆盘在中柱上,这个状态是2个圆盘的汉若塔游戏最优移动轨迹中不会出现的状态,所以返回-1.
说明
汉诺塔永远只有三步:
- 把n-1的盘子移动到缓冲区
- 把1号从起点移到终点
- 把缓冲区的n-1号盘子移动到终点
因此算法是找到最大圆盘的位置arr[N-1]在哪个柱子上,根据这个来判断到了哪一步
整个过程可以总结为:
1、如果最大圆盘在左柱上,则继续递归1~(i-1)个盘子的情况,其目标是从left(左柱)到buffer(中柱)
2、如果最大圆盘在右柱上,起码走完了2^(i-1)步,则继续递归1~(i-1)个盘子的情况,其目标是从buffer(中柱)到right(右柱)
3、如果最大圆盘在中柱上,则直接返回-1
代码(递归)
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
int process(vector<int>arr, int i, int left, int buffer, int right)
{
int res = 0;
if (i == -1)
{
return 0;
}
else if (arr[i] == buffer)
{
return -1;
}
else if (arr[i] == left)
{
return process(arr, i - 1, left,right ,buffer );
}
else
{
res +=process(arr, i - 1, buffer, left, right);
}
return res+pow(2,i);
}
int funoi2(vector<int>arr)
{
if (arr.size() == 0)
{
return -1;
}
int len=arr.size();
return process(arr, len - 1, 1, 2, 3);
int _tmain(int argc, _TCHAR* argv[])
{
int i, j;
int n = 3;
vector<int>arr = {3,3};
int res=funoi2(arr);
cout << res;
return 0;
}
代码(非递归)
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//汉诺塔进阶
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
//非递归算法
int funoi2(vector<int>arr)
{
if (arr.size() == 0)
{
return -1;
}
int left = 1;
int buffer = 2;
int right = 3;
int len = arr.size() - 1;
int res = 0;
int temp = 0;
while (len>=0)
{
if (arr[len] == buffer)
{
return -1;
}
if (arr[len] == left)
{
temp = buffer;
buffer=right;
right = temp;
}
else if (arr[len]==right)
{
res += pow(2,len);
temp = left;
left = buffer;
buffer = temp;
}
len--;
}
return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i, j;
int n = 3;
vector<int>arr = {3,3};
int res=funoi2(arr);
cout << res;
return 0;
}
来源:CSDN
作者:云帆之路Tony
链接:https://blog.csdn.net/weixin_42036617/article/details/104301199