因为是进行阶段的训练,所以比较清楚这个题是一个逻辑问题,因为这个次数有2的64次方之多,所以遍历是不可能的,所以就是在找规律,以汉诺塔的移动规律我先写了如下代码
#include<iostream>
using namespace std;
void yan(int n) {
if (n == 1)
cout << n << " ";
else
{
yan(n - 1);
cout << n << " ";
yan(n - 1);
}
}
int main()
{
int n;
while (cin >> n)
{
yan(n);
cout << endl;
}
}
然后随便敲了几个盘子,运行效果如下
可以看到当n大于1时,其移动就是在中间插入n,然后前后重复n-1的移动,题目是输出第几次移动哪个盘,如果次数是2的n-1次方就输出n,不是就在n-1个盘移动中找,就可以使用二分搜索去大幅度减少耗时,将其改成递归方式就是下面的代码。
过的代码如下
#include<iostream>
#include<cmath>
using namespace std;
int pan(int n, long long m) {
if (n == 1 && m == 1)
return 1;
long long mid = pow(2, n - 1);
if (m == mid)
return n;
else if (m > mid)
return pan(n - 1, m - mid);
else
return pan(n - 1, m);
}
int main() {
int n;
long long m;
while (cin>>n>>m,n||m)
cout << pan(n,m) << endl;
return 0;
}