杭电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;
}