• 汉诺塔问题


    算法:当只有一个盘子的时候,只需要从将A塔上的一个盘子移到C塔上。

      当A塔上有两个盘子是,先将A塔上的1号盘子(编号从上到下)移动到B塔上,再将A塔上的2号盘子移动的C塔上,最后将B塔上的小盘子移动到C塔上。

      当A塔上有3个盘子时,先将A塔上编号1至2的盘子(共2个)移动到B塔上(需借助C塔),然后将A塔上的3号最大的盘子移动到C塔,最后将B塔上的两个盘子借助A塔移动到C塔上。

      当A塔上有n个盘子是,先将A塔上编号1至n-1的盘子(共n-1个)移动到B塔上(借助C塔),然后将A塔上最大的n号盘子移动到C塔上,最后将B塔上的n-1个盘子借助A塔移动到C塔上。

      综上所述,除了只有一个盘子时不需要借助其他塔外,其余情况均一样(只是事件的复杂程度不一样)。

             

    Python

    def hanoi(n,x,y,z):
        if n==1:
            print(x,'-->',z)
        else:
            hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上
            hanoi(1,x,y,z)#将最底下的最后一个盘子从x移动到z上
            hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上
    n=int(input('请输入汉诺塔的层数:'))
    hanoi(n,'x','y','z')

    php

    <?php
     
    functionhanoi($n,$x,$y,$z){
     
    if($n==1){
     
    move($x,1,$z);
     
    }else{
     
    hanoi($n-1,$x,$z,$y);
     
    move($x,$n,$z);
     
    hanoi($n-1,$y,$x,$z);
     
    }
     
    }
     
    functionmove($x,$n,$z){
     
    echo'movedisk'.$n.'from'.$x.'to'.$z.'<br>';
     
    }
     
    hanoi(10,'x','y','z');
     
    ?>

    Java

    public class Hanoi {
        /**
        * 
        * @param n 盘子的数目
        * @param origin 源座
        * @param assist 辅助座
        * @param destination 目的座
        */
        public void hanoi(int n, char origin, char assist, char destination) {
            if (n == 1) {
                move(origin, destination);
            } else {
                hanoi(n - 1, origin, destination, assist);
                move(origin, destination);
                hanoi(n - 1, assist, origin, destination);
            }
        }
     
        // Print the route of the movement
        private void move(char origin, char destination) {
            System.out.println("Direction:" + origin + "--->" + destination);
        }
     
        public static void main(String[] args) {
            Hanoi hanoi = new Hanoi();
            hanoi.hanoi(3, 'A', 'B', 'C');
        }
    }

    C++

    #include<iostream>
    using namespace std;
    void hanoi(int n,char a,char b,char c)
    {
    if(n==1)
    cout<<n<<" "<<a<<" "<<c<<endl;
    else
    {
    hanoi(n-1,a,c,b);
    cout<<n<<" "<<a<<" "<<c<<endl;
    hanoi(n-1,b,a,c);
    }
    }
    int main()
    {
    int n;
    cout<<"输入正整数:"<<endl;
    cin>>n;
    cout<<"结果为"<<endl;
    hanoi(n,'A','B','C');
    return 0;
    } 

    C语言

    #include<stdio.h>
    voidhanoi(intn,charA,charB,charC)
    {
     
    if(n==1)
    {
    printf("Movedisk%dfrom%cto%c
    ",n,A,C);
    }
    else
    {
    hanoi(n-1,A,C,B);
    printf("Movedisk%dfrom%cto%c
    ",n,A,C);
    hanoi(n-1,B,A,C);
    }
    }
    main()
    {
    intn;
    printf("请输入数字n以解决n阶汉诺塔问题:
    ");
    scanf("%d",&n);
    hanoi(n,'A','B','C');
    return 0;
    }

    汉诺塔问题的非递归实现

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    //第0位置是柱子上的塔盘数目
    intzhua[100]={0},zhub[100]={0},zhuc[100]={0};
    charcharis(charx,intn)
    //左右字符出现顺序固定,且根据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';
    }
    }
    voidprint(charlch,charrch)
    //打印字符
    {
    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("	");
    inti;
    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("
    ");
    }
    voidHannuo(intn)
    {
    //分配2^n个空间
    bool*isrev;
    isrev=(bool*)malloc(sizeof(bool)*(int)pow(2,n));
    for(inti=1;i<pow(2,n);i++)
    isrev[i]=false;
    //循环计算是否逆序
    for(intci=2;ci<=n;ci++)
    {
    for(intzixh=(int)pow(2,ci-1);zixh<pow(2,ci);zixh+=4//初始值重复一次,自增值可加4,减少循环次数。
    isrev[zixh]=isrev[(int)pow(2,ci)-zixh];
    //该位置为中间位置,且奇次幂逆序,偶数幂不逆序
    isrev[(int)pow(2,ci)]=((ci-1)%2==0)?false:true;
    }
    charlch='A',rch;
    rch=(n%2==0?'B':'C');
    printf("%d	",1);
    printf("%c->%c",lch,rch);
    print(lch,rch);
    for(intk=2;k<pow(2,n);k++)
    {
    if(k%2==0)
    rch=charis(lch,n);
    else
    lch=charis(rch,n);
    printf("%d	",k);
    if(isrev[k])
    {
    printf("%c->%c",rch,lch);
    print(rch,lch);
    }
    else
    {
    printf("%c->%c",lch,rch);
    print(lch,rch);
    }
    }
    }
    intmain()
    {
    intn;
    printf("Inputthenum:");
    scanf("%d",&n);
    zhua[0]=n;
    for(inti=1;i<=n;i++)
    zhua[i]=n-i+1;
    Hannuo(n);
    return0;
    }
  • 相关阅读:
    Java 上传文件总结
    Java和C# MD5加密比较
    ORM映射框架总结数据操作(七)
    ORM映射框架总结数据操作(五)
    ORM映射框架总结数据操作(一)
    ORM映射框架总结数据操作(四)
    ORM映射框架总结数据操作(六)
    ORM映射框架总结文件下载
    STM32USART DMA_Interrupt例程的学习
    开始STM32的学习
  • 原文地址:https://www.cnblogs.com/lswit/p/4574388.html
Copyright © 2020-2023  润新知