分治算法示例

十年热恋 提交于 2020-02-15 22:02:11

通过一个例子来介绍分治算法的应用。一个袋子里有30枚银币,其中一枚银币为假,并且假银币和真银币一模一样,肉眼很难分辨,目前只知道假银币比真银币重量轻一点。请问如何找出假银币?
首先来分析一下寻找假银币的问题,可以采用递归分治的思想来求解这个问题,操作如下:
(1)首先为每个银币编号,然后将所有的银币等分为两份,放在天平的两边。这样就将区分30个银币的问题变为区分两堆银币的问题。
(2)因为假银币的重量较轻,因此天平较轻的一侧一定包含假银币。
(3)再将较轻的一侧中的硬银币等分为两份,重复上述做法。
(4)直到剩下两枚银币,便可用天平直接找出假银币。

int FalseCoin(int *coin,int low,int high)
{
	int i,sum1,sum2,sum3;//定义三个变量sum1为前半段和,sum2为后半段和,sum3为奇数中间的数
	int re;
	sum1=sum2=sum3=0;
	if(low+1=high)//只有两个数
	{
		if(coin[low]<coin[high])
		{
			re=low+1;
			return re;//返回假银币的位置
		}
		else
		{
			re=high+1;
			return re;
		}
	}
	if((high-low+1)%2==0)//偶数个银币
	{
		for(i=low;i<=low+(high-low)/2;i++)
		{
			sum1=sum1+coin[i];//前半段之和
		}
		for(i=low+(high-low)/2+1;i<=high;i++)
		{
			sum2=sum2+coin[i];//后半段之和
		}
		if(sum1>sum2)
		{
			re=FalseCoin(coin,low+(high-low)/2+1,high);
			return re;
		}
		else if(sum1<sum2)
		{
			re=FalseCoin(coin,low,low+(high-low)/2);
			return re;
		}
		else
		{
		}
	}
	else//奇数个银币
	{
		for(i=low;i<=low+(high-low)/2-1;i++)
		{
			sum1=sum1+coin[i];//前半段和
		}
		for(i=low+(high-low)/2+1;i++)
		{
			sum2=sum2+coin[i];//后半段和
		}
		sum3=coin[low+(high-low)/2];//奇数中间的那个数字
		if(sum1>sum2)
		{
			re=FalseCoin(coin,low+(high-low)/2+1,high);
			return re;
		}
		else if(sum1<sum2)
		{
			re=FalseCoin(coin,low,low+(high-low)/2-1);
			return re;
		}
		else
		{
		}
		if(sum1+sum3==sum2+sum3)//奇数中间的为假币
		{
			re=low+(high-low)/2+1;
			return re;
		}
	}
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!