经典指数          
原因
2107
浏览数
0
收藏数
 

有一个int数组arr其中只含有1、2和3,分别代表所有圆盘目前的状态,1代表左柱,2代表中柱,3代表右柱,arr[i]的值代表第i+1个圆盘的位置。比如,arr=[3,3,2,1],代表第1个圆盘在右柱上、第2个圆盘在右柱上、第3个圆盘在中柱上、第4个圆盘在左柱上。如果arr代表的状态是最优移动轨迹过程中出现的状态,返回arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的状态不是最优移动轨迹过程中出现的状态,则返回-1。 给定一个int数组arr及数组的大小n,含义如题所述,请返回一个int,代表所求的结果。 测试样例: [3,3] 返回:3

     举报   纠错  
 
切换
1 个答案

#include

#include

#include

using namespace std;

//这是一个不断缩小的子问题,考虑1到n-1时,说明第n个圆盘已经放好了

class Hanoi

{

private:

int chk(const vector& arr, int k, const int from, const int pass, const int to)

{

if(1==k)

{

if(from==arr[k-1])return 0; //只有一个圆盘且在from上那么就在最初状态

if(to == arr[k-1])return 1; //只有一个圆盘且在to上那么就在最终状态(只有一个圆盘只需一步)

return -1;

}

if(arr[k-1] == pass) //最大那个圆盘是不可能经过辅助塔的

{

return -1;

}

//当前最大的为第k个盘,初始位置位于当前的from上,

//若所给状态其也在from上,那么说明其没有移动过,不必考虑他,直接考虑子集1到k-1

if(arr[k-1] == from)

{

return chk(arr, k-1, from, to, pass);

}

//当前最大的为第k个盘,初始位置本应在from上但给出的状态是在to上,说明其发生了移动,我们把移动分为两部分,

//一部分是把1到k-1移到pass上,第k个移到to上,第二部分为后续移动到达给定状态,

//其中第一部分需要 1<<(k-1)步,第二部分是在从pass经from到to时形成的一个过程

if(arr[k-1]==to)

{

int tmp = chk(arr, k-1, pass, from, to);

if(-1==tmp)

{

return -1;

}

return (1 << k-1)+tmp;

}

}

public:

int chkStep(vector arr, int n)

{

if(n<=0)return -1;

if(arr.size()!=n)return -1;

if(arr[n-1]==2)return -1; //n-1也即最大的那个盘不可能会在第二个塔位上(最优路径下)

return chk(arr, n, 1, 2, 3);

}

};

int main()

{

vector arr;

arr.push_back(3);

arr.push_back(3);

Hanoi h;

cout << h.chkStep(arr, 2) << endl;

system("pause");

return 0;

}

 
切换
撰写答案