新人小白,问问关于汉诺塔的问题。
在http://topic.csdn.net/u/20110825/19/d06467a9-1431-478c-9ca7-a1bb3a67e429.html?seed=1320608711&r=77881296#r_77881296 中已经给出了答案,在此对作者不胜感激。
但是http://sznoi.cn/oj/ShowProblem?problemid=d093 要求,每一步之前应该打印出这一步的操作的板子是哪个。
这个该怎么处理?
[解决办法]
- C/C++ code
//汉诺塔问题#include<iostream.h>void move(char one,char anoth){ cout<<one<<"移动到"<<anoth<<endl;}void hanoi(int n,char no1,char no2,char no3){ // if (n==1) move(no1,no3); else { hanoi(n-1,no1,no3,no2);// move(no1,no3); hanoi(n-1,no2,no1,no3);// }}void main(){ void hanoi(int n,char no1,char no2,char no3); int m; cout<<"请输入A柱上的金盘子总数:"; cin>>m; cout<<"当有"<<m<<"个金盘子时,移动步骤依次为:"<<endl; hanoi(m,'A','B','C');}
[解决办法]
将递归转化为非递归,是理解递归的不2法门。
- C/C++ code
/*------------------------------------------------------用栈来实现Hanoi------------------------writer:neolyao 2012-1-21-----------------------------------------------------*/#include<stdio.h>#define MAX 100typedef struct DATA{ char x; char y; char z; int flag; //flag==1,表示还可以分解,若为0这不能分解 int num; //表示盘子个数}DATATYPE;void Hanoi(int n,char x,char y,char z);int main(){ int n; printf("请输入盘子的个数:"); scanf("%d",&n); Hanoi(n,'X','Y','Z'); return 0;}void Hanoi(int n,char x,char y,char z){ DATATYPE stack[MAX]; int x1,y1,z1,m,top=1; stack[top].num=n; stack[top].flag=1; stack[top].x=x; stack[top].y=y; stack[top].z=z; while(top) { if(stack[top].flag==1&&stack[top].num>1) { m=stack[top].num; //参数的传递==Hanoi(num,x,y,z); x1=stack[top].x; y1=stack[top].y; z1=stack[top].z; stack[top].num=m-1; //将第m-1个盘子经过x从y移到z==Hanoi(m-1,y,x,z) stack[top].flag=1; stack[top].x=y1; stack[top].y=x1; stack[top].z=z1; top++; stack[top].num=m; stack[top].flag=0; //将第m个盘子从x移到z==Move(m,x,z) stack[top].x=x1; stack[top].y=z1; top++; stack[top].num=m-1; stack[top].flag=1; stack[top].x=x1; //将第m-1个盘子从x经过z移到y==Hanoi(m-1,x,z,y) stack[top].y=z1; stack[top].z=y1; } while(top>0&&(stack[top].flag==0||stack[top].num==1)) { if(top>0&&stack[top].flag==0) //将第n个盘子从x移到z { printf("将第%d个圆盘从塔%c移动到%c\n",stack[top].num,stack[top].x,stack[top].y); top--; } if(top>0&&stack[top].num==1) //将第一个盘子从x移到z { printf("将第%d个圆盘从塔%c移动到%c\n",stack[top].num,stack[top].x,stack[top].z); top--; } } }}//请输入盘子的个数:3//将第1个圆盘从塔X移动到Z//将第2个圆盘从塔X移动到Y//将第1个圆盘从塔Z移动到Y//将第3个圆盘从塔X移动到Z//将第1个圆盘从塔Y移动到X//将第2个圆盘从塔Y移动到Z//将第1个圆盘从塔X移动到Z//Press any key to continue
[解决办法]
“给定一个小点的输入,完整单步跟踪一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出