1 问题描述
设有A、B、C3个塔座。
在塔座A上有一叠共n个圆盘。自上而下,由小到大地叠在一起,依次编号为1,2,…,n。
问题:要求将塔座A上的圆盘全部移到塔座C上,仍按同样顺序叠置。在移动圆盘时遵守以下规则:
- 每次只允许移动1个圆盘
- 任何时刻都不允许将较大的圆盘压在较小的圆盘之上
- 在规则1和2的前提下,可将圆盘移至任何一塔座上
2 分析
- 当n=1时,问题可以直接求解,一步完成
- 当n>1时,分三步完成:
- 将n-1个较小盘子设法移动到辅助塔座。
- 构造出一个比原问题规模小1的问题。
- 将最大的盘子从原塔座一步移至目标塔座
- 将n-1个较小的盘子设法从辅助塔座移至目标塔座
- 仍然是比原问题规模小1的问题。
- 将n-1个较小盘子设法移动到辅助塔座。
3 C++实现
#include <vector>
#include <cstdio>
void printTower(vector<vector<int>>&tower){
for(int i=0;i<tower.size();i++){
printf("第%d个塔: ",i+1);
for(int j=0;j<tower.at(i).size();j++){
printf(" %d",tower.at(i).at(j));
}
printf("\n");
}
printf("\n");
}
void move(vector<vector<int>>&tower,int src,int tar){
tower.at(tar).push_back(tower.at(src).back());
tower.at(src).pop_back();
printTower(tower);
}
void hanoi(vector<vector<int>>&tower,int n,int src,int tar,int aux){
if(n>0){
hanoi(tower,n-1,src,aux,tar);
move(tower,src,tar);
hanoi(tower,n-1,aux,tar,src);
}
}
void test1 (){
vector<vector<int>>tower;
tower.push_back(vector<int>());
tower.push_back(vector<int>());
tower.push_back(vector<int>());
tower.at(0).push_back(4);
tower.at(0).push_back(3);
tower.at(0).push_back(2);
tower.at(0).push_back(1);
printTower(tower);
hanoi(tower,4,0,2,1);
}