题目:http://acm.hdu.edu.cn/showproblem.php?pid=2511
AC代码(C++):
#include <iostream> #include <queue> #include <set> #include <string> #include <algorithm> #include <string.h> #include <math.h> #define INF 0x3f3f3f3f #define eps 1e-8 typedef unsigned long long ULL; using namespace std; void Hanoi(int n, ULL m, int from, int mid, int to) { ULL step = ((ULL)1 << (n - 1)) - 1; if (m <= step)Hanoi(n - 1, m, from, to, mid); else if (m == step + 1)cout << n << ' ' << from << ' ' << to << endl; else Hanoi(n - 1, m-1-step, mid, from, to); } int main() { int t; cin >> t; while (t--) { int n; ULL m; cin >> n >> m; Hanoi(n, m, 1, 2, 3); } //system("pause"); }
总结: 做这题首先要了解汉诺塔(Hanoi Tower)是怎么运作的. 要解决规模为n(即n层)的汉诺塔问题, 可以把问题分为三个阶段. 第一阶段, 把n-1个盘子放到mid上; 第二阶段, 把第n个盘子放到to上; 第三阶段, 把mid上的n-1个盘子放到to上. 而第一和第三阶段都是递归完成的, 而解决一次递归只需要第二阶段的1次移动, 所以规模为n的汉诺塔问题移动次数为2^n-1次. 故第一和第三阶段都只需移动2^(n-1)-1次. 那么对于一个输入m, 如果m小于等于2^(n-1)-1, 就说明这一步属于解决n规模问题的第一阶段, 如果m等于2^(n-1)-1+1, 则说明处于第二阶段, 可以直接得到答案, 如果大于2^(n-1)-1+1, 则说明在第三阶段. 那么在第一第三阶段的直接递归解决就好了.