ACM-4

杭电ACM-1997

汉诺塔问题的解决思路:
  先把A上的前 n-1个盘子借助C放到B上,在把第n个盘子放到C上,最后再把B上的前n-1个盘子借助A放到C上

对与此题:
   第n个盘子一定不可能出现在B上;
   若第n个盘子在A上,也就是说现在是处于把A上的前n-1个盘子借助C放到B上的过程,第n-2个盘子不可能出现在C上---->把B和C调换递归的进行判断;
   若第n个盘子在C上,也就是说现在是处于把B上的前n-1个盘子借助A放到C上的过程,第n-2个盘子不可能出现在A上---->把A和B调换递归的进行判断;
   若第n个盘子在B上,返回0;(递归结束)
   递归终止的条件是盘子数为0,返回1;

具体实现代码如下:

#include <stdio.h>

 

int Fun(int num,int *A,int *B,int *C)
{
    //如果num为0直接返回1
    //如果最大的盘子在A上,则把A上的所有的盘子都向前移动一个,并且把B和C交换
   //如果最大的盘子在C上,则把C上所有的盘子都向前移动一个,并且把A和B交换
   //否则返回0(因为最大的盘子不可能在C上)
    if(num==0)return 1;
   
    if(A[1]==num){

      //如果把i的声明放到if的外面,提交到杭电上一直会报编译错误(很令人纠结的地方)所以不得不在每个for语句前都声明一次
        int i;  

       for( i = 1;;i++){
            if(A[i]==-1)break;
            A[i]=A[i+1];
        }
        return Fun(num-1,A,C,B);
    }else if(C[1]==num){
        int i;
        for( i = 1;;i++){
            if(C[i]==-1)break;
            C[i]=C[i+1];
        }
        return Fun(num-1,B,A,C);
    }else{
        return 0;
    }
   
}

int main()
{
   
    int A[80],B[80],C[80];
    int a,b,c;
    int num;
    int T;
    int i;
    scanf("%d",&T);
    for( i = 0;i < 80;i++){
        A[i]=B[i]=C[i]=-1;
    }
    while (T--){
        scanf("%d%d",&num,&a);
        for( i = 1;i<=a;i++){
            scanf("%d",&A[i]);
        }
        scanf("%d",&b);
        for( i = 1;i<=b;i++){
            scanf("%d",&B[i]);
        }
        scanf("%d",&c);
        for( i = 1;i<=c;i++){
            scanf("%d",&C[i]);
        }
        if(Fun(num,A,B,C)==1){
            printf("true\n");
        }else{
            printf("false\n");
        }
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值