hd1997

http://acm.hdu.edu.cn/showproblem.php?pid=1997

思路:

(1)首先判断是不是已经完全放好了或者还没有开始移动,这样就不用考虑是否最优化了,即所有的盘子在C柱上或者所有的盘子在A柱上,这样是合法的,直接输出true。
(2)【我们考虑盘号最大的盘子第n号盘子,移动方向为A-->C,它只可能在A柱或者C柱上,如果在B柱上我们可以直接返回false--①】;
如果盘号最大的盘子在A柱上,说明其它盘子正在进行A-->B的操作,所以考虑移动的那个n-1个盘子,然后同样按①判断,只不过,最大盘号变成了n-1,而移动方向变成了A-->B;
如果盘号最大的盘子在C柱上,说明其它盘子正在进行B-->C的操作,所以考虑移动的那个n-1个盘子,然后同样按①判断,只不过,最大盘号变成了n-1,而移动方向变成了B-->C;
利用递归按这种方式不断地进行①操作。
#include <stdio.h>
int hanio(int n, int a[], int b[], int c[], int m, int p, int q)  //考虑最大盘号盘子的位置,a通过b移向c
{
	int i;
	if(n == 0) 
		return 1;  //当柱子上没有盘子的时候,当然算是正确的

	//通过y从x-->z,最大盘号在x柱和z柱上才是正确的,而在y柱上就是错误的

	for(i=0; i<p; i++)
	{
		if(b[i] == n) //错误
			return 0;  
	}

	for(i=0; i<m; i++)
	{
		if(a[i] == n)  //最大盘号在x柱上,合法,说明其它盘子正在x-->y,剩下的盘子最大盘号为n-1,递归考虑n-1个盘子x-->y的过程
			return hanio(n-1,a,c,b,m,q,p);  //考虑第二大盘号n-1,同时改变移动方向
	}

	for(i=0; i<q; i++)
	{
		if(c[i] == n)  //最大盘号在z柱上,合法,说明其它盘子正在y-->z,剩下的盘子最大盘号为n-1,递归考虑n-1个盘子y-->z的过程
			return hanio(n-1,b,a,c,p,m,q);  //考虑第二大盘号n-1,同时改变移动方向
	}
}


int main()
{
	int t;
	int i;
	int n;
	int m,p,q;
	int a[70],b[70],c[70];
	while(scanf("%d",&t)!=EOF)
	{
		while(t--)
		{
			scanf("%d",&n); //盘号是1~n

			scanf("%d",&m);
			for(i=0; i<m; i++)
			{
				scanf("%d",&a[i]);
			}

			scanf("%d",&p);
			for(i=0; i<p; i++)
			{
				scanf("%d",&b[i]);
			}

			scanf("%d",&q);
			for(i=0; i<q; i++)
			{
				scanf("%d",&c[i]);
			}

			if(m == n || q == n)  //移动之前和移动完成都是合法状态
				printf("true\n");
			else
			{
				if(hanio(n,a,b,c,m,p,q))
					printf("true\n");
				else
					printf("false\n");
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值