河内之塔

说明:河内之塔(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);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值