说明:河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数 搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。
解法:如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两 个盘子,也就是:A->B、A->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递 回处理。事实上,若有n个盘子,则移动完毕所需之次数为2^n -1,所以当盘数为64时,则所需 次数为:264- 1 =18446744073709551615为5.05390248594782e+16年,也就是约5000世纪,如果对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。
标准版
#include <stdio.h>
void hanoi(int n,char A, char B, char C){
if(n == 1){
printf("Move sheet %d from %cto %cn", n, A, C);
}
else{
hanoi(n-1, A, C, B);
printf("Move sheet %d from %c to %cn", n, A, C);
hanoi(n-1, B, A, C);
}
}
int main(){
int n;
printf("请输入盘数:");
scanf("%d", &n);
hanoi(n, 'A', 'B', 'C');
return 0;
}
加强版
#include <windows.h>
#include <stdio.h>
//常量定义区
#define MAX_VALUE 100//定义数组最大值
#define DATA_1 1
#define DATA_2 2
#define DATA_3 3
#define SPEED 800000
//全局变量定义区
int data_1[MAX_VALUE][MAX_VALUE];
int data_2[MAX_VALUE][MAX_VALUE];
int data_3[MAX_VALUE][MAX_VALUE];
int data_l_1=0;
int data_l_2=0;
int data_l_3=0;
int max_n;
int move_num=0;
//函数定义区
void hanoi(int n, char A, char B, char C);
int int_input(int i,int j);
void program_introduction();
void initialization_data();
void initialization_data_1(int n);
void show_data(int n,int K);
void record_data(int n,char A,char C);
void sleep_order();
int main()
{
int n;
program_introduction();
printf("请输入盘数:");
n=int_input(1,100);
max_n=n;
initialization_data_1(n);
show_data(n,DATA_1);
system("cls");
hanoi(n, 'A', 'B', 'C');
system("pause");
return 0;
}
void hanoi(int n, char A, char B, char C)
{
if(n == 1){
printf("Move sheet %2d from %c to %c , move number %4dn", n, A, C,++move_num);
record_data(n,A,C);
show_data(max_n,1);
show_data(max_n,2);
show_data(max_n,3);
sleep_order();
system("cls");
}
else{
hanoi(n-1, A, C, B);
printf("Move sheet %2d from %c to %c , move number %4dn", n, A, C,++move_num);
record_data(n,A,C);
show_data(max_n,1);
show_data(max_n,2);
show_data(max_n,3);
sleep_order();
system("cls");
hanoi(n-1, B, A, C);
}
}
void program_introduction()
{
printf("Created At: 20170802n");
printf("Algorithm Gossip: 河内之塔n");
printf("广州航海学院 - 吴南辉 n");
printf("Referenced By: http://www.wunanhui.wang:81n");
printf("n");
printf("说明 河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越");
printf("战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说");
printf("创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置");
printf("64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三");
printf("根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数");
printf("搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。n");
printf("n");
printf("解法 如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,");
printf("就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两");
printf("个盘子,也就是:A->B、A ->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递");
printf("回处理。事实上,若有n个盘子,则移动完毕所需之次数为2^n - 1,所以当盘数为64时,则所需");
printf("次数为:2 64 - 1 = 18446744073709551615为5.05390248594782e+16年,也就是约5000世纪,如果");
printf("对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。n");
printf("n");
system("pause");
system("cls");
}
int int_input(int i,int j)//整形数据输入函数
{
int a=-100,k=0;
while(a>j||a<i){
if(k!=0){printf("数据错误,请重新输入n"); }
scanf("%d",&a);
k++;
}
return a;
}
void initialization_data(){
int i,j;
for(i=0;i<MAX_VALUE;i++){
for(j=0;j<MAX_VALUE;j++){
data_1[i][j]=0;
data_2[i][j]=0;
data_3[i][j]=0;
}
}
}
void initialization_data_1(int n){
int i,j;
for(i=0;i<n;i++){
for(j=0;j<=i;j++){data_1[i][j]=1;}
++data_l_1;
}
}
void show_data(int n,int K){
int i,j;
if(K==DATA_1){printf("A:n");}
if(K==DATA_2){printf("B:n");}
if(K==DATA_3){printf("C:n");}
for(i=0;i<n;i++){
printf("%2d | ",i+1);
for(j=n-1;j>=0;j--){
if(K==DATA_1){
if(data_1[i][j]==1){printf("■");}
else{printf(" ");}
}
if(K==DATA_2){
if(data_2[i][j]==1){ printf("■");}
else{printf(" ");}
}
if(K==DATA_3){
if(data_3[i][j]==1){ printf("■");}
else{printf(" "); }
}
}
for(j=0;j<n;j++){
if(K==DATA_1){
if(data_1[i][j]==1){printf("■");}
else{printf(" ");}
}
if(K==DATA_2){
if(data_2[i][j]==1){printf("■");}
else{printf(" "); }
}
if(K==DATA_3){
if(data_3[i][j]==1){printf("■");}
else{printf(" ");}
}
}
printf("n");
}
}
void record_data(int n,char A,char C)
{
int i,j;
if(A=='A'){
for(j=0;j<n;j++){data_1[max_n-data_l_1][j]=0;}
--data_l_1;
}
else if(A=='B'){
for(j=0;j<n;j++){ data_2[max_n-data_l_2][j]=0;}
--data_l_2;
}
else if(A=='C'){
for(j=0;j<n;j++){ data_3[max_n-data_l_3][j]=0;}
--data_l_3;
}
if(C=='A'){
for(j=0;j<n;j++){ data_1[max_n-data_l_1-1][j]=1;}
++data_l_1;
}
else if(C=='B'){
for(j=0;j<n;j++){ data_2[max_n-data_l_2-1][j]=1;}
++data_l_2;
}
else if(C=='C'){
for(j=0;j<n;j++){data_3[max_n-data_l_3-1][j]=1;}
++data_l_3;
}
}
void sleep_order(){
usleep(SPEED);
}