首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

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

2012-09-12 
暑期 每日一练acm题第四题经典汉诺塔 求递归算法 楼主泪奔啊C/C++ code/********************************

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

C/C++ code
/***********************************************汉诺塔问题不多说了;输入:    输入正整数n表示有n个盘子在第一个柱子上;输出:    move 移动的盘子标号 from 起始位置 to 移动后位置输入样例:3输出样例:move 1 from a to cmove 2 from a to bmove 1 from c to bmove 3 from a to cmove 1 from b to amove 2 from b to cmove 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小时才编出来,倒是对了稍微欣慰一点) 递归高手速度来吧 最近发帖多分没多少了 大家见谅

[解决办法]
好长。
[解决办法]
C/C++ code
/****************************************************************汉诺塔的要求就是有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;} 

热点排行