题目:
A、B、C 三个桌子,其中A桌子上放了几个大小不同的盘子,盘子的排列顺序为: 从上到下,依次从小到大递增;现要求把这些盘子从 A 桌子上移动到 C 桌子上,盘子移动时有一点要求:每次移动必须保证三张桌子上大盘子在下、小盘子在上。实现函数打印最优移动轨迹
举例说明:
(1) A 上一张 盘子时
移动顺序: A -> C
(2)A上有两张盘子时:
移动顺序: A->B
B->C
C->A
递归分析:
子问题:
步骤1:将圆盘1~n-1从A移动到B
步骤2:单独把圆盘n从from移动到to
步骤3:把圆盘1~n-1从B移动到C
结束条件:
圆盘只有1个,直接把这个圆盘从A移动到C即可
代码如下:
void Hanoi(int n)
{
void Process(int n, char from, char mid, char to);
if (n <= 0)
return;
Process(n, 'A', 'B', 'C');
}
void Process(int n, char from, char mid, char to)
{
if (n == 1)
{
cout << from << "->" << to<<endl;
}
else
{
Process(n - 1, from, to, mid);
Process(1, from, mid, to);
Process(n - 1, mid, from, to);
}
}
思考
为什么可以打印出所有的步骤,不是只是打印出来了只有一个即n==1的情况吗?
因为只有一个的情况,不只是从A移动到C,还有其他的,其他的路径也要打印出来
移动的最少步骤数
(1)首先求都在A上的圆盘1~n,,如果都移动到C上的最小步骤数,假设为S(n)
(2)根据上面的步骤,S(n)=步骤1的步骤总数+1+步骤3的步骤总数=S(n-1)+1+S(n-1)
(3)由S(1)=1,和S(n)+1=2(S(n-1)+1),根据等比数列求和公式可以求出S(n)=2^n-1