暑期 每日一练acm题 第四题 经典汉诺塔 求递归算法 楼主泪奔啊

qq14344545 2012-07-25 12:28:16

/***********************************************
汉诺塔问题不多说了;
输入:
输入正整数n表示有n个盘子在第一个柱子上;
输出:
move 移动的盘子标号 from 起始位置 to 移动后位置

输入样例:
3

输出样例:

move 1 from a to c
move 2 from a to b
move 1 from c to b
move 3 from a to c
move 1 from b to a
move 2 from b to c
move 1 from a to c

*****************************************************/
#include<stdio.h>
int main()
{
int x[3][64] = {0},n,t = 0,t1 = 0,t2 = 0,k = 0,i,j,e,f;
char q,p;
scanf("%d",&n);
for( i = 0 ; i < n ; i++ )
x[0][i] = n - i;
if( n % 2 == 0)
{
while ( x[0][0]!=0 || x[1][0]!=0 )
{
if( k == 0 )
{
for( i = j = 0; x[j][i] != 1 ; i++ )
{
if( x[j][i] == 0 )
{
i = -1;
j++;
continue;
}
}
x[j][i] = 0;
switch(j)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
j++;
if( j == 3 )
j -= 3;
switch(j)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
for( i = 0 ; x[j][i] != 0 ; i++ );
x[j][i] = 1;
k = 1;
printf("move 1 from %c to %c\n",q,p);
}
else if( k == 1 )
{
j++;
if( j == 3 )
j -= 3;
for( i = 1; x[j][i] != 0 ; i++ )
{
if( x[j][0] == 0 )
{
i = 0;
break;
}
}
i--;
t1 = x[j][i];
e = j;
e++;
if( e == 3 )
e -= 3;
for( f = 1; x[e][f] != 0 ; f++ )
{
if( x[e][0] == 0 )
{
f = 0;
break;
}
}
f--;
t2 = x[e][f];
if( t1 == 0 )
t1 = 65;
else if ( t2 == 0 )
t2 = 65;
if( t1 > t2 )
{
if( t1 != 65 )
i++;
x[j][i] = x[e][f];
x[e][f] = 0;
t = t2;
switch(e)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
switch(j)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
}
else
{
if( t2 != 65 )
f++;
x[e][f] = x[j][i];
x[j][i] = 0;
t = t1;
switch(j)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
switch(e)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
}
printf("move %d from %c to %c\n",t,q,p);
k = 0;
}
}
}
else
{
while ( x[0][0]!=0 || x[1][0]!=0 )
{
if( k == 0 )
{
for( i = j = 0; x[j][i] != 1 ; i++ )
{
if( x[j][i] == 0 )
{
i = -1;
j++;
continue;
}
}
x[j][i] = 0;
switch(j)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
j--;
if( j == -1 )
j += 3;
switch(j)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
for( i = 0 ; x[j][i] != 0 ; i++ );
x[j][i] = 1;
k = 1;
printf("move 1 from %c to %c\n",q,p);
}
else if( k == 1 )
{
j++;
if( j == 3 )
j -= 3;
for( i = 1; x[j][i] != 0 ; i++ )
{
if( x[j][0] == 0 )
{
i = 0;
break;
}
}
i--;
t1 = x[j][i];
e = j;
e++;
if( e == 3 )
e -= 3;
for( f = 1; x[e][f] != 0 ; f++ )
{
if( x[e][0] == 0 )
{
f = 0;
break;
}
}
f--;
t2 = x[e][f];
if( t1 == 0 )
t1 = 65;
else if ( t2 == 0 )
t2 = 65;
if( t1 > t2 )
{
if( t1 != 65 )
i++;
x[j][i] = x[e][f];
x[e][f] = 0;
t = t2;
switch(e)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
switch(j)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
}
else
{
if( t2 != 65 )
f++;
x[e][f] = x[j][i];
x[j][i] = 0;
t = t1;
switch(j)
{
case 0 : q = 'a'; break;
case 1 : q = 'b'; break;
case 2 : q = 'c'; break;
}
switch(e)
{
case 0 : p = 'a'; break;
case 1 : p = 'b'; break;
case 2 : p = 'c'; break;
}
}
printf("move %d from %c to %c\n",t,q,p);
k = 0;
}
}
}
return 0;
}

楼主递归真心不怎么会 算算阶乘 叠加还会点(实际上迭代更合适,所以递归用的次数少练得少) 这回碰上汉诺塔我就知道世界末日到了 楼主用循环做的 大神指点一下递归算法吧 细说一下递归技巧的 什么时候用递归 递归不是计算次数多浪费时间吗? 有关递归的都说一下吧 楼主编的那个代码就别喷了(楼主想死的心都有了,用了2小时才编出来,倒是对了稍微欣慰一点) 递归高手速度来吧 最近发帖多分没多少了 大家见谅
...全文
241 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
skillart 2012-07-26
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
void hanoi(int ,char ,char ,char );
int main()
{
int m;
printf("input the number of diskes:");
scanf("%d",&m);
printf("The step to move %d diskes:\n",m);
hanoi(m,'A','B','C');
system("pause");
}
void hanoi(int n,char a,char b,char c)
{
static int i=1;
if(n==1)
printf("(%d) %c to %c\n",i++,a,b);
else
{
hanoi(n-1,a,c,b);
printf("(%d) %c to %c\n",i++,a,b);
hanoi(n-1,c,b,a);
}
}
RiqueZhang 2012-07-26
  • 打赏
  • 举报
回复

#include <stdio.h>
void move(int vIndex, char vFrom, char vTo)
{
printf("Move %d from %c to %c\n", vIndex, vFrom, vTo);
}
void hanoi(int vNum, char vSrc, char vDest, char vAssist)
{
if(0 >= vNum) return;
if(1 == vNum) return move(1, vSrc, vDest);

hanoi(vNum-1, vSrc, vAssist, vDest);
move(vNum, vSrc, vDest);
hanoi(vNum-1, vAssist, vDest, vSrc);
}
int main()
{
hanoi(3, 'A', 'C', 'B');
return 0;
}
RiqueZhang 2012-07-26
  • 打赏
  • 举报
回复

#include <stdio.h>
void move(int vIndex, char vFrom, char vTo)
{
printf("Move %d from %c to %c\n", vIndex, vFrom, vTo);
}
void hanoi(int vNum, char vSrc, char vDest, char vAssist)
{
if(0 >= vNum) return;
if(1 == vNum) return move(1, vSrc, vDest);

hanoi(vNum-1, vSrc, vAssist, vDest);
move(vNum, vSrc, vDest);
hanoi(vNum-1, vAssist, vDest, vSrc);
}
int main()
{
hanoi(3, 'A', 'C', 'B');
return 0;
}
nanjingnew4 2012-07-26
  • 打赏
  • 举报
回复
/****************************************************************
汉诺塔的要求就是有A,B,C三个位置,最终目的就是从A->C
基本算法有两种:递归和迭代
你这种是递归
void hanoi(int n, char A, char B, char C);
n表示A位置最下面的盘子,B表示借助作用(不一定就是真正的B盘子(这个B表示借助),这个要想清楚)
*****************************************************************/

#include <stdio.h>

void hanoi(int n, char A, char B, char C) //递归函数
{
if(n == 1)
{
printf("Move sheet %d from %c to %c\n", n, A, C); //如果A位置只有一个盘子,不需要借助B,直接移动
}
else
{
hanoi(n-1, A, C, B);
//当n>1,要将最A最下面的盘子移置C,需要先将该盘子上面的n-1的盘子先移到B
printf("Move sheet %d from %c to %c\n", n, A, C);
//然后将n从A移置C
hanoi(n-1, B, A, C);
//接着就是将这n-1的盘子借助A从B->C
//上述就是个将第n个盘子从A->C 完整的操作
//接下来就是将hanoi(n-1, B, A, C)也就是n-1个盘子继续操作,继续做递归循环n-1,n-2,n-3 .... 3,2,1直到只剩一个盘子

}
}
int main()
{
int n;
printf("请输入盘数:");
scanf("%d", &n);
hanoi(n, 'A', 'B', 'C');
return 0;
}


递归这东西,我也不懂,我听某人说过一句话,写多了对理解有帮助,写写就顺了
smsgreenlife 2012-07-25
  • 打赏
  • 举报
回复
#include "iostream"
using namespace std;

void hanoi(int n, char a, char c, char b)//把a上的n个盘子通过b移到c上
{
if (n>1)
{
hanoi(n-1, a, b, c);
cout<<a<<"->"<<c<<endl;
hanoi(n-1, b, c,a);
}
else
{
cout<<a<<"->"<<c<<endl;//从a上拿一个盘子放到c上
}
}

int main()
{
hanoi(4, 'a', 'c', 'b');
return 0;
}
qq14344545 2012-07-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
C/C++ code
#include <stdio.h>
#include <stdlib.h>

int move(int n, int s, int O, int D, int T)
{
if(s == 1)
{
printf("move %d From %d To %d\n", n, O, D);
return 0;
……
[/Quote] 说一下递归的调用问题呗
夏天__ 2012-07-25
  • 打赏
  • 举报
回复
好长。
csdmdsc 2012-07-25
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>

int move(int n, int s, int O, int D, int T)
{
if(s == 1)
{
printf("move %d From %d To %d\n", n, O, D);
return 0;
}
else
{
move(n - 1, s - 1, O, T, D);
move(n, 1, O, D, T);
move(n - 1, s - 1, T, D, O);
return 0;
}
}

int main ()
{
//move all the disk from tower 1 to tower 2
move(3, 3, 1, 2, 3);
return 0;

}
要拍,请轻拍。
csdmdsc 2012-07-25
  • 打赏
  • 举报
回复
汉诺塔有这么长?我记得跟你所给程序的注释差不多长的。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧