100层汉诺塔问题

输入层数,能快速得到移动的次数,层数在10层以下可以得到移动的步骤。

#include<stdio.h>
#define ll long long 
#define Cnum 10000000
ll res[5]={0}; 
int tot=0,c=0;
void get_res(int n){
   int i; ll adw=0; res[tot]=1;
  //计算2^n 
  while(n--){
  	  for(i=0;i<=tot;i++){
		res[i]=res[i]*2+adw;
		adw=res[i]/Cnum;res[i]%=Cnum;
		if(tot==i&&adw)tot++;
		}
  } i=0;
   //减去1  
  while(!res[i])
  i++;
	res[i]--;
  if(i!=0)
  	while(i--)
  	res[i]=Cnum-1;//若需借位 
}
void move(int disk,char start,char end)
{
    printf("step:%d,move %c to %c\n",++c,start,end);
    return;
}
void hanoi(int n,char A,int B,char C)
{
	if(n<=10)
	{
    if(n==1)
        move(1,A,C);//disk=1时,直接将disk从A移动到C
    else
    {
        hanoi(n-1,A,C,B);//第一步,将n-1个盘从A移动到B,其中C为辅助盘
        move(n,A,C);//第二步,将n号盘直接从A移动到C
        hanoi(n-1,B,A,C);//第三步,将B盘上的n-1个盘递归调用
    }
   	}
}
int main_1(int n){
  	int i;
     get_res(n);//获得结果 
          while(!res[tot])
		  tot--;//去掉首位 0 
    printf("%ld",res[tot]);//输出首位 
         for(i=tot-1;i>=0;i--) 
		 printf("%07ld", res[i]);//按每7位输出 不足补0 
    printf("\n");
 return 0;
}
int main()
{
    int disk_num;
    printf("input diak_num:\n");
    scanf("%d",&disk_num);
    //移动。 
    hanoi(disk_num,'A','B','C');
    //计算移动的次数。 
    printf("移动的次数为:");
    main_1(disk_num);
    return 0;
}

 

### C++ 汉诺塔问题动画演示实现代码 以下是基于C++和SimpleCG库的一个汉诺塔动画演示实现代码。该代码通过递归逻辑控制盘子的移动,并结合图形绘制技术展示整个过程。 #### 主要功能描述 1. 使用递归函数完成汉诺塔问题的核心逻辑。 2. 利用图形库(如SimpleCG或SDL2)动态绘制盘子的移动过程。 3. 提供可视化的界面,让用户能够直观理解汉诺塔的工作原理。 #### 完整代码示例 以下是一个完整的C++代码示例,用于实现汉诺塔动画: ```cpp #include <iostream> #include <graphics.h> // 如果使用SimpleCG或其他图形库,请确保已安装并配置好环境 using namespace std; // 初始化柱子的位置参数 const int X_OFFSET = 100; const int Y_BASE = 400; const int COLUMN_DISTANCE = 200; int columnX[3] = {X_OFFSET, X_OFFSET + COLUMN_DISTANCE, X_OFFSET + 2 * COLUMN_DISTANCE}; // 绘制单个盘子 void drawDisk(int x, int y, int width) { setcolor(WHITE); rectangle(x - width / 2, y - 10, x + width / 2, y + 10); floodfill(x, y, WHITE); } // 清除单个盘子 void eraseDisk(int x, int y, int width) { setcolor(BLACK); rectangle(x - width / 2, y - 10, x + width / 2, y + 10); floodfill(x, y, BLACK); } // 移动盘子 void moveDisk(int fromColumn, int toColumn, int diskWidth, int diskHeight) { int startX = columnX[fromColumn]; int startY = Y_BASE - diskHeight; int endX = columnX[toColumn]; int endY = Y_BASE - diskHeight; // 先清除原位置的盘子 eraseDisk(startX, startY, diskWidth); // 动画效果:逐移动到目标位置 for (int i = 0; i <= 100; ++i) { int currentX = startX + (endX - startX) * i / 100; int currentY = startY + (endY - startY) * i / 100; drawDisk(currentX, currentY, diskWidth); delay(10); // 控制动画速度 eraseDisk(currentX, currentY, diskWidth); } // 在新位置重新绘制盘子 drawDisk(endX, endY, diskWidth); } // 递归实现汉诺塔逻辑 void hanoiAnimation(int n, int src, int aux, int dst, int* heights) { if (n == 1) { moveDisk(src, dst, 50 + 10 * (n - 1), heights[n - 1]); // 调整宽度随数变化 } else { hanoiAnimation(n - 1, src, dst, aux, heights); moveDisk(src, dst, 50 + 10 * (n - 1), heights[n - 1]); hanoiAnimation(n - 1, aux, src, dst, heights); } } int main() { initwindow(800, 600, "Hanoi Tower Animation"); // 设置初始高度数组 const int NUM_DISKS = 3; int heights[NUM_DISKS]; for (int i = 0; i < NUM_DISKS; ++i) { heights[i] = 20 * (NUM_DISKS - i); } // 绘制初始状态 for (int i = 0; i < NUM_DISKS; ++i) { drawDisk(columnX[0], Y_BASE - heights[i], 50 + 10 * i); } // 开始执行汉诺塔动画 hanoiAnimation(NUM_DISKS, 0, 1, 2, heights); getch(); closegraph(); return 0; } ``` --- #### 关键点解析 1. **递归逻辑** 上述代码实现了经典的汉诺塔递归逻辑[^3],其中`hanoiAnimation`函数负责处理盘子的移动顺序。 2. **图形绘制** 使用了`drawDisk`和`eraseDisk`函数分别绘制和擦除盘子,模拟盘子的移动过程。为了简化开发流程,这里假设用户已经安装了支持图形绘制的库(如SimpleCG或SDL2)。如果未安装相应库,则需先配置环境[^2]。 3. **动画效果** `moveDisk`函数通过逐帧更新盘子的位置,创建平滑的动画效果。每次移动都会调用`delay`函数暂停一小段时间,从而让动画更加流畅[^1]。 4. **可扩展性** 用户可以通过修改`NUM_DISKS`变量调整汉诺塔数,但需要注意的是,数越高,计算量越大,可能会影响性能。 --- #### 注意事项 - 需要确保计算机环境中已正确安装图形库(如SimpleCG或SDL2),否则无法运行此代码。 - 若使用其他图形库替代SimpleCG,应根据具体API调整绘图部分的代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值