C语言程序设计(汉诺塔问题)
C语言编程题题库(1)
1.编程输出显示汉诺塔问题中移动的过程。
2.从键盘任意输入一个4位数x,编程计算x的每一位数字相加之和(忽略整数前的正负号)。
例如,输入x为1234,则有1234分离出其千位1,百位2,十位3,个位4,然后计算1+2+3+4=10,并输出10。
3.利用递归的方法,求n!的结果.n从键盘输入。
4.编程计算1×2×3+3×4×5+...+99×100×101的值。
5.利用π/2=2/1×2/3×4/3×4/5×6/5×6/7×……的前100项之积计算π的值。
6.利用π/4=1-1/3+1/5-1/7+……计算π的值,直到最后一项的绝对值小于10的-4次方为止,要求统计总共累加了多少项。
7.编程计算 a+aa+aaa+...+aa...a(n个a)的值,n和a的值由键盘输入。
8.打印所有的"水仙花数"。
所谓"水仙花数"是指一个三位数,其各位数字的立方和等于该数本身。
例如,153是"水仙花数",因为1*1*1+5*5*5+3*3*3=153。
9.利用e=1+1/1!+1/2!+1/3!+……+1/n!,计算e的近似值,当最后一项的绝对值,小于10的-5次方,认为达到了精度要求。
要求统计总共累加了多少项。
10.2^0+2^1+…+2^63.11.九九乘法表上(下)三角。
12.杨辉三角。
13.从键盘按由小到大输入10个整数存于数组中,再从键盘任意输入一个整数x,将x有序的插入其中.要求在main函数进行输入和输出,插入的过程在自定义函数中完成。
14.从键盘10个整数存于数组中,再从键盘任意输入一个整数x,若存在则将x删除,若x不存在则输出"不存在!"的信息.要求在main函数进行输入和输出,删除的过程在自定义函数中完成。
汉诺塔游戏-----用C++编的
#ifndef HANIO_H_#define HANIO_Hclass Stack{private:enum{ MAX=50 };int m_node[MAX];int m_top;int m_size;int m_index;public:Stack();~Stack() { };bool Isfull() { return m_top==MAX-1 ;}; //堆栈满则返回TRUE bool Isempty() { return m_top==-1;}; //堆栈空则返回TRUE int Top() { return m_top; };int TopValue() { return m_node[m_top];};int GetDataFromIndex(int i) { return m_node[i]; };int GetIndex() { return m_index; } ;void SetIndex(int index) { m_index = index; };int Size() { return m_top+1; };bool Push(int data);bool Pop(int * pData);int MoveToNext();void OutPrint();};class Hanio{Stack m_stack[3];int m_num; //盘数int m_steps; //移动次数int m_times; //完成所用时间void print(char ch,int n);public:Hanio(int num=3);~Hanio() {};void GameStart();bool MoveFromTo(int x,int y); //从x号盘移动到y号盘void DrawPaletes(char ch='*'); //打印3个堆的盘子bool IsFinished() ; //结束返回TURE;int Solve(char from,char to,char auxiliary,int n); //求解其解法路径};#endif//hanio.cpp#include "hanio.h"#include <iostream>#include<cstdlib>#include<cstring>#include<cctype>#include<windows.h>Stack::Stack(){m_top=-1;m_index=m_top;for(int i=0;i<MAX;i++)m_node[i]=0;}bool Stack::Push(int data){if(Isfull())return false;m_top++;m_node[m_top]=data;m_index=m_top;return true;}bool Stack::Pop(int *pData){if(Isempty())return false;*pData=m_node[m_top];m_node[m_top]=0;m_top--;m_index=m_top;return true;}int Stack::MoveToNext(){int temp=m_index;m_index--;return m_node[temp];}void Stack::OutPrint(){if(m_top!=-1){for(int i=0;i<=m_top;i++)std::cout<<"["<<m_node[i]<<"]";}}///////////////////////////////////////Hanio::Hanio(int num){m_num=num;m_steps=0;m_times=0;for(int i=num;i>=1;i--)m_stack[0].Push(i);//m_stack[0].OutPrint();}void Hanio::print(char ch,int n){for(int i=1;i<=n;i++)std::cout<<ch;}void Hanio::DrawPaletes(char ch){int max;max=m_stack[0].Size()>m_stack[1].Size() ? m_stack[0].Size() : m_stack[1].Size();max=m_stack[2].Size()>max ? m_stack[2].Size() : max;//std::cout<<"Max:"<<max<<std::endl;m_stack[0].SetIndex(max-1);m_stack[1].SetIndex(max-1);m_stack[2].SetIndex(max-1);for(int i=1;i<=max;i++){int data1=m_stack[0].MoveToNext();int data2=m_stack[1].MoveToNext();int data3=m_stack[2].MoveToNext();if(data1==0)print(' ',20);else{print(' ',10-data1);print(ch,2*data1);print(' ',10-data1);}if(data2==0)print(' ',20);else{print(' ',10-data2);print(ch,2*data2);print(' ',10-data2);}if(data3==0)print(' ',20);else{print(' ',10-data3);print(ch,2*data3);print(' ',10-data1);}std::cout<<std::endl;}}bool Hanio::MoveFromTo(int x,int y){m_steps++; //计算所走的步数if(m_stack[x].Isempty()){std::cout<<x<<" pallete is empty ! continue !"<<std::endl; std::cin.get();return false;}if(m_stack[y].Isempty()){int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}else{if(m_stack[x].TopValue()>m_stack[y].TopValue()){std::cout<<"The board can't move from "<<x<<" plate to " <<y<<" plate!"<<std::endl;std::cin.get();return false;}else{int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}}}bool Hanio::IsFinished(){return m_stack[2].Top()==m_num-1;}void Hanio::GameStart(){using namespace std;UINT StartTime=::GetTickCount();UINT EndTime;while(1){system("cls");print('-',80);cout<<"steps: "<<m_steps; print(' ',20);cout<<"Used time: "<<m_times<<endl;print('-',80);cout<<endl; cout<<endl; print(' ',10); cout<<"A";print(' ',19); cout<<"B"; print(' ',19);cout<<"C"<<endl<<endl;Hanio::DrawPaletes();cout<<endl; cout<<endl;print('-',80);//测试游戏是否结束if(Hanio::IsFinished()){cout<<"你好强呀!从今天开始,维护世界和平的任务就交给你那!"<<endl;cin.get();break;}//输入命令并左相应的处理char szCommand[50];cout<<">>";cin.getline(szCommand,50);if(stricmp(szCommand,"QUIT")==0 || stricmp(szCommand,"Q")==0)break;if(stricmp(szCommand,"HELP")==0 || stricmp(szCommand,"H")==0){cout<<" 本游戏说明:"<<endl;cout<<" 该游戏由DAVID用C++编程,花费了一个多下午的时间呢!!!,由命令行来控制铁饼的移动:"<<endl;cout<<" QUIT / Q : 退出程序"<<endl;cout<<" HELP / H : 查看该说明"<<endl;cout<<" XY : X,Y的取值为A,B,C,意思时把X木桩最上面的铁饼移到Y 木桩"<<endl;cout<<" SOLVE / S : 显示求解该问题(移动铁饼)的最优路径..."<<endl; cin.get();}char ch1=toupper(szCommand[0]);char ch2=toupper(szCommand[1]);if( ch1=='A' && ch2=='B')Hanio::MoveFromTo(0,1);else if ( ch1=='A' && ch2=='C')MoveFromTo(0,2);else if ( ch1=='B' && ch2=='A')MoveFromTo(1,0);else if ( ch1=='B' && ch2=='C')MoveFromTo(1,2);else if ( ch1=='C' && ch2=='A')MoveFromTo(2,0);else if ( ch1=='C' && ch2=='B')MoveFromTo(2,1);else{cout<<"Bad command !"<<endl;cin.get();}//统计游戏所用时间EndTime=GetTickCount();m_times=(EndTime-StartTime)/1000;}}int Hanio::Solve(char from,char to,char auxiliary,int n) {if(n==1)return 0;}//main.cpp#include<iostream>#include"hanio.h"#include<cstdlib>using namespace std;int StartPicture();//返回选择的盘数int main(){int number;number=StartPicture();Hanio hanio(number);hanio.GameStart();return 0;}void print(char ch,int n){for(int i=1;i<=n;i++)std::cout<<ch;}int StartPicture(){using namespace std;int number;system("cls");system("color fc");print(' ',20);print('-',25);cout<<endl;print(' ',20);cout<<" Hanio(汉诺塔)"<<endl;print(' ',20);print('-',25);cout<<endl;print(' ',40);print('-',5);cout<<"By David"<<endl;print('=',80);cout<<" 相传在某一座古庙中有3根木桩,有24个铁盘由小到大放置在一根木柱上,庙中流传者一个传说:\"如果能把24个铁盘, 从一根木桩移动到另一个木桩,且必须遵守如下规则:"<<endl;cout<<endl;print(' ',5);cout<<"1. 每天只能动一个盘,而且只能从最上面的铁盘开始搬动."<<endl; print(' ',5);cout<<"2. 必须维持较小的铁盘在上方的原则"<<endl;cout<<endl;cout<<"这两个原则,则当24个铁盘完全般到另一个木桩时,世界就回永久和平!!"<<endl;cout<<"游戏的玩法可以在命令行中输入HELP查看"<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<"再此输入你要搬的铁盘数(建议在1--10值间,太多回花费很长时间的)"<<endl;print('=',80);cout<<">>";cin>>number;cin.get();system("cls");return number;}。
汉诺塔问题实验报告
1.实验目的:通过本实验,掌握复杂性问题的分析方法,了解汉诺塔游戏的时间复杂性和空间复杂性。
2.问题描述:汉诺塔问题来自一个古老的传说:在世界刚被创建的时候有一座钻石宝塔(塔A),其上有64个金碟。
所有碟子按从大到小的次序从塔底堆放至塔顶。
紧挨着这座塔有另外两个钻石宝塔(塔B和塔C)。
从世界创始之日起,婆罗门的牧师们就一直在试图把塔A 上的碟子移动到塔C上去,其间借助于塔B的帮助。
每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。
当牧师们完成任务时,世界末日也就到了。
3.算法设计思想:对于汉诺塔问题的求解,可以通过以下三个步骤实现:(1)将塔A上的n-1个碟子借助塔C先移到塔B上。
(2)把塔A上剩下的一个碟子移到塔C上。
(3)将n-1个碟子从塔B借助于塔A移到塔C上。
4.实验步骤:1.用c++ 或c语言设计实现汉诺塔游戏;2.让盘子数从2 开始到7进行实验,记录程序运行时间和递归调用次数;3.画出盘子数n和运行时间t 、递归调用次数m的关系图,并进行分析。
5.代码设计:Hanio.cpp#include"stdafx.h"#include<stdlib.h>#include<stdio.h>#include<iostream>void hanoi(int n,char x,char y,char z){if(n==1){printf("从%c->搬到%c\n",x,z);}else{hanoi(n-1,x,z,y);printf("从%c->%c搬到\n",x,z);hanoi(n-1,y,x,z);}}void main(){int m ;printf("input the number of diskes:");scanf("%d",&m);printf("The step to moving %3d diskes:",m);hanoi(m,'a','b','c');}自定义头文件:#pragma once#include"targetver.h"#include<stdio.h>#include<tchar.h>结果如下:6.递归应用中的Hanoi塔问题分析1)Hanoi塔问题中函数调用时系统所做工作一个函数在运行期调用另一个函数时,在运行被调用函数之前,系统先完成3件事:①将所有的实参、返回地址等信息传递给被调用函数保存。
C语言程序设计课程设计报告---汉诺塔问题
XXXX大学计算机科学与技术学院课程设计报告2012 — 2013学年第一学期课程名称C/C++高级语言程序设计课程设计设计题目小游戏和图形处理汉诺塔问题学生姓名XXX学号XXXXXXX专业班级XXXXXXXXXXX指导教师XX2012 年X 月XX 日目录一、课程设计问题描述 (1)1、课程设计题目 (1)2、设计任务要求 (1)二、总体设计 (1)1、设计思路 (1)2、汉诺塔求解流程图 (2)三、详细设计 (2)1、汉诺塔问题描述 (2)2、算法分析 (3)3、实现递归的条件 (4)4、用C语言实现 (4)四、程序运行结果测试与分析 (4)1、打开Microsoft Visual C++ 6.0操作平台输入以下的源代码 (4)2、编译源代码 (5)3、组建 (5)4、执行 (5)5、运行结果 (6)6、按任意键结束程序 (7)五、结论与心得 (7)六、参考文献 (8)七、附录:程序源代码 (8)一、课程设计问题描述1、课程设计题目汉诺塔问题2、设计任务要求输入盘子数(2个以上有效),移动速度,开始演示汉诺塔移动的步骤,要求:盘子A,B,C柱需要自己绘制,初始时盘子在A柱上通过B柱最终移动到C 柱上,显示出盘子在几个柱之间的移动过程。
二、总体设计1、设计思路对于一个类似的这样的问题,任何一个人都不可能直接写出移动盘子的每一个具体步骤。
可以利用这样的统筹管理的办法求解:我们假设把该任务交给一个僧人,为了方便叙述,将他编号为64。
僧人自然会这样想:假如有另外一个僧人能有办法将63个盘子从一个座移到另一个座,那么问题就解决了,此时僧人A B C64只需这样做:(1).命令僧人63将63个盘子从A座移到C座(2).自己将最底下的最大的一个盘子从A座移到C座(3).再命令僧人63将63个盘子从B座移到C座为了解决将63个盘子从A座移到B座的问题,僧人63又想:如果能再有一个僧人62能将62个盘子移动到另一座,我就能将63个盘子从A座移动到B座。
c语言课程设计汉诺塔
c语言课程设计汉诺塔一、教学目标本节课的教学目标是让学生掌握汉诺塔问题的解法,理解其背后的算法思想,培养逻辑思维能力和编程能力。
具体分为以下三个部分:1.知识目标:使学生了解汉诺塔问题的定义、解法和算法思想,理解递归算法的原理及其在解决汉诺塔问题中的应用。
2.技能目标:培养学生运用C语言实现汉诺塔问题的解决方案,提高编程实践能力。
3.情感态度价值观目标:培养学生独立思考、合作交流的学习习惯,增强对计算机科学的兴趣和热情。
二、教学内容本节课的教学内容主要包括以下几个部分:1.汉诺塔问题的定义和解法:介绍汉诺塔问题的背景,讲解其解法及步骤。
2.递归算法的原理:讲解递归算法的基本概念、特点及其在解决汉诺塔问题中的应用。
3.C语言实现汉诺塔问题:引导学生运用C语言编写汉诺塔问题的解决方案,并进行调试和优化。
4.算法分析和改进:分析汉诺塔问题的算法复杂度,探讨如何优化算法性能。
三、教学方法为了达到本节课的教学目标,采用以下几种教学方法:1.讲授法:讲解汉诺塔问题的定义、解法和递归算法的原理。
2.案例分析法:分析实际案例,让学生了解递归算法在解决汉诺塔问题中的应用。
3.实验法:引导学生动手实践,用C语言实现汉诺塔问题的解决方案。
4.讨论法:学生进行小组讨论,分享算法优化思路,培养合作交流能力。
四、教学资源本节课的教学资源包括以下几个方面:1.教材:选用《C程序设计》等相关教材,为学生提供理论知识的学习参考。
2.参考书:推荐《算法导论》等参考书籍,帮助学生深入了解算法原理。
3.多媒体资料:制作PPT、教学视频等多媒体资料,辅助学生理解和记忆知识点。
4.实验设备:为学生提供计算机、编程环境等实验设备,方便学生动手实践。
五、教学评估本节课的教学评估主要包括以下几个方面:1.平时表现:评估学生在课堂上的参与度、提问回答等情况,占比20%。
2.作业:评估学生完成的汉诺塔问题相关练习,包括C语言代码编写和调试,占比30%。
c语言汉诺塔程序设计
c语言汉诺塔程序设计
下面是一个用C语言实现汉诺塔问题的程序:
```c
#include <stdio.h>
void hanoi(int n, char from, char to, char aux) {
if (n == 1) {
printf("Move disk 1 from %c to %c\n", from, to); return;
}
hanoi(n - 1, from, aux, to);
printf("Move disk %d from %c to %c\n", n, from, to); hanoi(n - 1, aux, to, from);
}
int main() {
int n;
printf("Enter the number of disks: ");
scanf("%d", &n);
printf("Steps to solve the Hanoi Tower problem:\n"); hanoi(n, 'A', 'C', 'B');
return 0;
}
```
这个程序使用递归的方式解决汉诺塔问题。
函数`hanoi`接受四个参数:盘子的数量`n`,起始柱子`from`,目标柱子`to`,辅助柱子`aux`。
当盘子数量为1时,直接将盘子从起始柱子移动到目标柱子。
否则,先将n-1个盘子从起始柱子移动到辅助柱子,然后将最后一个盘子从起始柱子移动到目标柱子,最后将n-1个盘子从辅助柱子移动到目标柱子。
汉诺塔问题动态演示
H(n,A,B,C)
H ( 3, A, B, C )
H(n,A,B,C)
H ( 3, A, B, C )
Stack
Output 0 C B A 1 C A B 2 A C B 3 A B C A A C B
H(n-1,a,c,b)
H ( 2, A, C, B )
H(n-1,b,a,c) H ( 1, C, A, B )
H(n-1,a,c,b) H ( 0, C, B , A)
H ( 3, A, B, C )
Stack
Output 0 A C B 1 C A B 2 A C B 3 A B C A A C C B B
H(n-1,a,c,b)
H ( 2, A, C, B )
H(n-1,b,a,c)
H ( 1, C, A, B )
H(n-1,b,a,c) H ( 0, A, C , B )
n a b c
void hanoi ( int n, char a, char b, char c ) { if ( n >= 1 ) { hanoi ( n-1, a, c, b) ; printf(“%c -->%c\n“,a,c); hanoi (n-1, b, a, c) ; } }
H(n,A,B,C)
H ( 3, A, B, C )
Stack
Output A A 1 C A B 2 A C B 3 A B C C C B B
汉诺塔问题实验报告
游戏的时间复杂性和空间复杂性。 2.问题描述:
汉诺塔问题来自一个古老的传说:在世界刚被创建的时候有 一座钻石宝塔(塔 A),其上有 64 个金碟。所有碟子按从大到小的次 序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔 B 和 塔 C)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔 A 上的碟子移动到塔 C 上去,其间借助于塔 B 的帮助。每次只能移 动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。 当牧师们完成任务时,世界末日也就到了。 3.算法设计思想:
8、总结
5
缓存大小
通过对汉诺塔算法的分析让我更清楚的认识到了不同的算法对 程序性能的影响,也让我明白掌握了算法将会有助于提高软件的开 发。
6
2)Hanoi 塔问题递归程序的复杂度分析
① 运行 hanoi 程序的时间
程序 hanoi.c 在硬件环境为赛扬 400MHz、内存 128M 的计算平台 (不同机器运行时间有一定差别)运行,可得出如下时间结果:
盘子数
时间结果
<=12 个
<=1 秒
14 个
2秒
16 个
13 秒
20 个
204 秒
② 时间复杂度
自定义头文件 :#pragma once
#include "targetver.h" #include <stdio.h> #include <tchar.h>
结果如下:
2
6.递归应用中的 Hanoi 塔问题分析 1)Hanoi 塔问题中函数调用时系统所做工作
一个函数在运行期调用另一个函数时,在运行被调用函数之前,系 统先完成 3 件事:
有趣的c语言代码
有趣的c语言代码在计算机编程领域中,C语言无疑是居于重要地位的一种语言。
它简洁明了,具有高度的灵活性,其语法规范和基本结构也有着非常强的适用性,依旧是很多应用领域的首选语言。
但是,除了作为一门实用的编程语言外,C语言也具备着不少有趣的面向场景和实现思路。
有时候我们不妨放开心态,花一点时间去探索一些优美、神奇或者古怪的代码,或许不仅可以带来好玩的游戏体验,还可以深刻领略计算机编程这一领域的魅力所在。
以下是几个有趣的C语言代码:1. Hello World!这是许多人接触编程时会碰到的第一行代码,既简单又经典。
用C 语言实现只需一行:include <stdio.h>int main(){printf("Hello, World!");return 0;}这段代码的功能很简单,输出 "Hello, World!"。
2. 回文字检测给定一个字符串,判断其是否为回文字符串。
这也是许多入门程序员接触的练手题。
bool isPalindrome(char *s){int len = strlen(s);for (int i = 0; i < len / 2; ++i)if (s[i] != s[len - 1 - i])return false;return true;}这段代码通过比较字符串中左右两端字符是否相同,完成回文检测。
3. 汉诺塔游戏汉诺塔是一个经典的数学谜题,至今仍是计算机课程和聚会游戏的热门选择之一。
在C语言中实现汉诺塔游戏的代码不仅具备实用价值,同时也挑战了程序设计师的算法思考能力。
void hanoi(int n, char A, char B, char C){if (n == 1)printf("%c -> %c\n", A, C);else{hanoi(n - 1, A, C, B);hanoi(1, A, B, C);hanoi(n - 1, B, A, C);}}这段代码通过递归实现了汉诺塔游戏的具体操作,将汉诺塔复杂的问题转化为简单的递归关系。
Hanoi(汉诺)塔问题
A
B
C
11:59
31
将2个盘子从B移到C的过程
A
将2个盘子从B移到C的过程
A
B
C
11:59
33
• 由上面的分析可知:将n个盘子从A座移到 C座可以分解为以下3个步骤:
(1) 将A上n-1个盘借助C座先移到B座上 (2) 把A座上剩下的一个盘移到C座上 (3) 将n-1个盘从B座借助于A座移到C座上
将62个从A到C
……
A
11:59
B
C
12
第2个和尚的做法
将1个从A到B
……
A
11:59
B
C
13
第2个和尚的做法
将1个从A到B
……
A
11:59
B
C
14
第2个和尚的做法
将62个从C到B
……
A
11:59
B
C
15
第2个和尚的做法
将62个从C到B
……
A
11:59
B
C
16
第3个和尚的做法 第4个和尚的做法 第5个和尚的做法 第6个和尚的做法 第7个和尚的做法 …… 第63个和尚的做法
B
C
6
第1个和尚的做法
将1个从A到C
……
A
11:59
B
C
7
第1个和尚的做法
将1个从A到C
……
A
11:59
B
C
8
第1个和尚的做法
将63个从B到C
……
A
11:59
B
C
9
第1个和尚的做法
将63个从B到C
……
A
C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64
汉诺(Hanoi)塔问题(C#版)
汉诺(Hanoi)塔问题(C#版)
⼀个只能⽤递归解决的数学问题;问题描述:古代有⼀个梵塔,塔内有3个座,A、B、C,开始时A座有64个盘,盘⼦⼤⼩不等,⼤的在上,⼩的在下。
有⼀个⽼和尚想把这64个盘⼦从A座移到C座(如图所⽰),但每次只允许移动⼀个盘,且在移动过程中在3个座上始终保持⼤盘在下,⼩盘在上。
在移动地程中可以⾏⽤B座,要求编程序打印出移动的步骤。
逆向推理:1.假如⼀个和尚能把上⾯63个盘⼦先搬到B座,第⼆个和尚再把最⼤的那个移到C,第三个和尚再把63个盘⼦移到C座;⾄此整个⼯作就完成的。
2.问题是怎么才能把63个盘⼦移到B座,按照同样的⽅法,先把62个盘⼦选移到C座
,再把第63个盘⼦移到B座,最后再将62个盘⼦移到B座。
3……如此类推;
4.从上⾯分析可以看出:只有等后⾯那个和尚搬完盘⼦,前⾯的和尚才能够去完成任。
让我们来栈的数据结构:数据的处理只在⼀端处理,且是先进后出。
所以⽤递归的⽅法去处理是正确的。
(汉诺塔图)
汉诺塔问题解决⽅案
如果你发现有什么错误之处,请指出!谢谢了。
汉诺塔演示
汉诺塔演示.txt你不能让所有人满意,因为不是所有的人都是人成功人士是—在牛B的路上,一路勃起你以为我会眼睁睁看着你去送死吗?我会闭上眼睛的摘要:该文对经典的“汉诺塔”问题进行了详细的分析,并用C语言实现。
通过问题的具体实现,使学习者了解问题的全过程,推广到一般。
关键词:汉诺塔;递归;C语言Algorithm Analysis and C Realization of Hanio IssueBAI Hui-bo1,GAO Rui-ping2(1.Qinhuangdao Branch of Daqing Petroleum Institute, Qinhuangdao 066004, China;2.Hebei Normal University of Science and Technology, Qinhuangdao 06600, China)Abstract: This text carries on detailed analysis about classical Hanio issue and provides realization of algorithm in C.Through concrete realization of the problem,can make learners observe the whole course which solves this issue and Extend to the general.Key words: hanio; recursive; the C programming language1 问题描述汉诺塔是一个经典的数学问题,其具体描述如下:有三根相邻的塔子,标号为A,B,C,A塔子上从下到上按金字塔状叠放着n个不同大小的圆盘,现在把所有盘子借助于A,B,C三个塔子一个一个移动到塔子C上,并且每次移动在同一根塔子上都不能出现大盘子在小盘子上方.根据问题描述得到以下规则:1)圆盘必须一个一个的移动;2)大的圆盘必须在小圆盘的下方或单一圆盘;3)满足规则2)的序列可以出现在A,B,C任意一根塔子上。
汉诺塔程序设计报告
VC++作业电信学院电子0801班张海滨20809050汉诺塔程序设计报告一、题目汉诺塔(Towers of Hanoi)问题二、设计要求1、在窗口中画出初始时塔和碟子的状态。
2、可以以自动或手动两种方式搬移碟子。
3、自动搬移可以通过定时器或多线程的方法,每一次移动的时间间隔可以自定,以人眼观察比较舒服为宜,每一次的移动过程如能实现动画最好。
4、定义塔的描述类和碟子的描述类。
5、在程序中,碟子的数目及每次移动的时间间隔可以通过对话框设置(也应该有默认值)。
6、支持暂停功和继续的功能(在自动搬移过程中可以暂停,并继续)。
7、暂停后,可以将当前的状态保存(碟子和塔的组合关系)。
8、可以从7中保存的文件中读出某个状态,并继续移动。
三、问题分析1、已知有三个塔(1、2、3)和n个从大到小的金碟子,初始状态时n个碟子按从大到小的次序从塔1的底部堆放至顶部。
2、要求把碟子都移动到塔2(按从大到小的次序从塔2的底部堆放至顶部)。
3、每次移动一个碟子。
4、任何时候、任何一个塔上都不能把大碟子放到小碟子的上面。
5、可以借助塔3。
(图1-1)图1-1首先考虑a杆下面的盘子而非杆上最上面的盘子,于是任务变成了:1、将上面的63个盘子移到b杆上;2、将a杆上剩下的盘子移到c杆上;3、将b杆上的全部盘子移到c杆上。
将这个过程继续下去,就是要先完成移动63个盘子、62个盘子、61个盘子....1个盘的工作。
四、算法选择汉诺塔程序设计算法的实质就是递归递归思想的运用。
现将其算法简述如下:为了更清楚地描述算法,可以定义一个函数hanoi(n,a,b,c)。
该函数的功能是:将n个盘子从塔a上借助塔b移动到塔c上。
这样移动n 个盘子的工作就可以按照以下过程进行:1) hanoi(n-1,a,c,b);//将n-1个金盘由a借助c移到b2) 将最下面的金盘从a移动到c上;3) hanoi(n-1,b,a,c);//将b上的n-1个盘借助a移到c重复以上过程,直到将全部的盘子移动到塔c上时为止。
汉诺塔问题的程序实现(hanoi塔)
汉诺塔问题的程序实现(hanoi塔)问题重述:有三根柱A、B、C,在柱A上有N块盘⽚,所有盘⽚都是⼤的在下⾯,⼩⽚能放在⼤⽚上⾯。
现要将A上的N块盘⽚移到C柱上,每次只能移动⼀⽚,⽽且在同⼀根柱⼦上必须保持上⾯的盘⽚⽐下⾯的盘⽚⼩,输⼊任意的N,输出移动⽅法。
(注意:这是⼀个古⽼的传说,传说是如果把64个盘⼦由A柱移到了C柱的话,那么世界末⽇就到了,事实上如果要把64个盘⼦从A柱移到C柱的话,即使⽤计算机运算,也要计算数亿年,所以这个预⾔未必不是真实。
)【分析】我们可以这样考虑,当n=1时,我们只要直接将A柱的盘⼦移到C柱,当n>1时,我们可以先把n-1个盘⼦由A柱通过C柱移到B 柱,此时就可以把A柱剩下的最后⼀个盘⼦直接移到C柱,这样接下来只要把n-1个盘⼦通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表⽰将n个盘⼦从a通过b移到c1.只要求输出搬运的次数#includeusing namespace std;int m=0;void move(){m++;}void I(int n){if(n==1)move();else{I(n-1);move();I(n-1);}}int main(){I(3);cout<cout<<"输出完毕!"<return 0;}更加简单的⽅法!#includeusing namespace std;int fact(int n){if(n==1)return(1);elsereturn((2*fact(n-1)+1));}int main(){cout<}2.不仅要求输出搬运的次数,⽽且要输出每个步骤的详细搬运#includeusing namespace std;int m=0;void Move(int n,char x,char y){cout<<"把"<m++;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){int i;cout<<"请输⼊圆盘数"<cin>>i;Hannoi(3,'a','b','c');cout<<"总的搬运次数"<cout<<"输出完毕!"<return 0;}}另外⼀种不利⽤递归的解法(很抱歉,我⾃⼰也没调出来,实在太复杂了)#includeusing namespace std;//圆盘的个数最多为64const int MAX = 1;//⽤来表⽰每根柱⼦的信息struct st{int s[MAX]; //柱⼦上的圆盘存储情况int top; //栈顶,⽤来最上⾯的圆盘char name; //柱⼦的名字,可以是A,B,C 中的⼀个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//⼊栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输⼊圆盘的个数st ta[3]; //三根柱⼦的信息⽤结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从⼤到⼩的顺序放在柱⼦A 上for (int i=0; ita[0].s[i] = n - i;//柱⼦B,C 上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int j=0; jta[1].s[j] = ta[2].s[j] = 0;//若n 为偶数,按顺时针⽅向依次摆放A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n 为奇数,按顺时针⽅向依次摆放A C B {ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; isum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针⽅向把圆盘1 从现在的柱⼦移动到下⼀根柱⼦ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱⼦上可以移动的圆盘移动到新的柱⼦上if (k < max){ //把⾮空柱⼦上的圆盘移动到空柱⼦上,当两根柱⼦都为空时,移动较⼩的圆if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk " << ch << " from " << ta[(i+1)%3].name << " to " << ta[(i-1)%3].name << endl; }}}}补充知识:【典型例题1】求阶乘n!#includeusing namespace std;int fact(int n){if(n==0)return(1);elsereturn(n*fact(n-1)); }int main(){cout<。
微课-汉诺塔问题教案
本微课适用范围如下所示:课程所属学科:计算机适用专业:计算机应用技术、计算机软件工程、电子信息适用课程:C语言程序设计、C++程序设计、JAVA程序设计、数据结构适用对象:有一定编程基础的同学《汉诺塔问题》微课教案学院(部):软件学院系(教研室):网络教研授课教师:杨珺职称:副教授时间复杂度为:O(2n)程序实现部分汉诺塔问题的递归实现:#include<stdio.h>void hanoi(int n,char A,char B,char C){if(n==1){printf("Move disk %d from %c to %c\n",n,A,C);}else{hanoi(n-1,A,C,B);printf("Move disk %d from %c to %c\n",n,A,C);hanoi(n-1,B,A,C);}}main(){int n;printf("请输入数字n以解决n阶汉诺塔问题:\n");scanf("%d",&n);hanoi(n,'A','B','C');}●汉诺塔算法的非递归实现C++源代码#include <iostream>using namespace std;//圆盘的个数最多为64const int MAX = 64;//用来表示每根柱子的信息struct st{int s[MAX]; //柱子上的圆盘存储情况int top; //栈顶,用来最上面的圆盘char name; //柱子的名字,可以是A,B,C中的一个int Top()//取栈顶元素{return s[top];}int Pop()//出栈return s[top--];}void Push(int x)//入栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输入圆盘的个数st ta[3]; //三根柱子的信息用结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从大到小的顺序放在柱子A上for (int i=0; i<n; i++)ta[0].s[i] = n - i;//柱子B,C上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int i=0; i<n; i++)ta[1].s[i] = ta[2].s[i] = 0;//若n为偶数,按顺时针方向依次摆放 A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n为奇数,按顺时针方向依次摆放 A C Bta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; i<y; i++)sum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if (k < max){ //把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i+1)%3].name<< " to " << ta[(i-1)%3].name << endl;}}}}汉诺塔问题的非递归实现#include <stdio.h>#include <math.h>#include <stdlib.h>//第0位置是柱子上的塔盘数目int zhua[100]={0},zhub[100]={0},zhuc[100]={0};char charis(char x,int n)//左右字符出现顺序固定,且根据n值奇偶而不同{switch(x){case 'A':return (n%2==0)?'C':'B';case 'B':return (n%2==0)?'A':'C';case 'C':return (n%2==0)?'B':'A';default:return '0';}}void print(char lch,char rch)//打印字符{if(lch=='A'){switch(rch){case 'B':zhub[0]++;zhub[zhub[0]]=zhua[zhua[0]]; zhua[zhua[0]]=0;zhua[0]--;break;case 'C':zhuc[0]++;zhuc[zhuc[0]]=zhua[zhua[0]]; zhua[zhua[0]]=0;zhua[0]--;break;default:break;}}if(lch=='B'){switch(rch){case 'A':zhua[0]++;zhua[zhua[0]]=zhub[zhub[0]]; zhub[zhub[0]]=0;zhub[0]--;break;case 'C':zhuc[0]++;zhuc[zhuc[0]]=zhub[zhub[0]]; zhub[zhub[0]]=0;zhub[0]--;break;default:break;}}if(lch=='C'){switch(rch){case 'A':zhua[0]++;zhua[zhua[0]]=zhuc[zhuc[0]];zhuc[zhuc[0]]=0;zhuc[0]--;break;case 'B':zhub[0]++;zhub[zhub[0]]=zhuc[zhuc[0]];zhuc[zhuc[0]]=0;zhuc[0]--;break;default:break;}}printf("\t");int i;printf("(");for(i=1;i<=zhua[0];i++)printf(" %d ",zhua[i]);printf(")");printf("(");for(i=1;i<=zhub[0];i++)printf(" %d ",zhub[i]);printf(")");printf("(");for(i=1;i<=zhuc[0];i++)printf(" %d ",zhuc[i]);printf(")");printf("\n");}void Hannuo(int n){//分配2^n个空间bool *isrev;isrev=(bool *)malloc(sizeof(bool)*(int)pow(2,n)); for(int i=1;i<pow(2,n);i++)//循环计算是否逆序for(int ci=2;ci<=n;ci++){for(int zixh=(int)pow(2,ci-1);zixh<pow(2,ci);zixh+=4) //初始值重复一次,自增值可加4,减少循环次数。
汉诺塔问题非递归算法
汉诺塔问题非递归算法
汉诺塔问题是一个经典的递归算法问题,但也可以使用非递归的方式解决。
下面是一种非递归算法的实现思路:
1. 创建三个栈,分别命名为A、B、C,表示三个柱子。
2. 对于n个盘子的汉诺塔问题,首先将所有盘子按从大到小的顺序依次压入栈A中。
3. 定义一个变量count,用来记录移动步数,初始值为0。
4. 如果n为奇数,则执行步骤5;如果n为偶数,则执行步骤6。
5. 循环执行以下操作:
5.1 将栈A的栈顶元素弹出,放入栈B中;
5.2 将栈A中剩余的n-1个盘子移到栈C中;
5.3 将栈B中的盘子移到栈C中;
5.4 将栈A作为辅助栈,栈B作为目标栈,栈C作为源栈,重复步骤5.1~5.3,直到栈A为空。
6. 循环执行以下操作:
6.1 将栈A的栈顶元素弹出,放入栈C中;
6.2 将栈A中剩余的n-1个盘子移到栈B中;
6.3 将栈C中的盘子移到栈B中;
6.4 将栈A作为辅助栈,栈C作为目标栈,栈B作为源栈,重复步骤6.1~6.3,直到栈A为空。
通过上述非递归算法,可以按照汉诺塔问题的规则将所有的盘子从栈A移动到栈B,并记录移动的步骤数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("the step of move %d diskes :",m);
tian(m,'A','B','C');
} void tian(int n,int x,int y,int z)
66 67
{void move(int x,int y); if(n==1) move(x,z);
else {tian(n-1,x,z,y); move(x,y); tian(n-1,y,x,z);
C 语言程序设计(汉诺塔设计)
#include<stdio.h>
void main()
{void tian(int n,int x,int y,int z);
/*函数声明*/
int m;
printf("please enter the number of diskes:\n");
scanf("%d",&m);
/*当我选定这一行的时候 然后单击组间选择调试 run to_ 发现不管输入的 x 值是多少 ABC 的值都是 65
后来才发现原来是他们所代表的十进制的值*/
/*这里是递归函数的结束条件*/
}
}
void move(int x, int y)
/*
定义 move 函数用来显示移动的路线*/
{printf("%c——>%c\n",x,y);
3 个盘子 可以简化为。。。。*/
}
/*汉洛塔问题:如果有 N 个盘子 那么可以简化为 n-1 个盘子和一个盘子来处理,只要先把 上面的 n-1 个盘子从 A——>B 把第 n 个盘子由 A——>C 再把 n-1 个盘子由 B——>C
即可;
n-1 盘子 那么可以简化为 n-2 个盘子和一个盘子来处理 只要 把
上面的 n-2 个盘子从 A——>B 把第 n 个盘子由 A——>C 再把 n-1 个盘子由 B——>C
即可;
n-3 盘子 那么可以简化为 n-3 个盘子和一个盘子来处理 只要 把
上面的 n-4 个盘子从 A——>B 把第 n 个盘子由 A——>C 再把 n-1 个盘子由 B——>C 即可;
N-子 那么可以简化为 3 个盘子和一个盘子来处理 只要 把 上面的 3 个盘子有 a 到 b 把第 4 个盘子由 a 到 c 再把上面的三个盘子由 b 到 c;