【基础算法】分治算法 & C++实现

 简要介绍:

        分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。下面的硬币问题就是分治算法的一种典型算法题。


●硬币问题

        在下面我们将硬币分为1和0两个值,1为真硬币,0为假硬币。找偶数枚硬币和奇数枚硬币将其随机排成一列,其中有一个假硬币,用分治算法寻找出这枚假硬币所在的位置。如下两图所示:

当硬币个数为偶数时(10枚):当硬币个数为奇数时(13枚):

代码实现: 

#include<iostream>
using namespace std;
#define maxsize 20
class fenzhi {
public:
	int falsecoin(int low, int high);
	void showresult();
	int num;
	int coin[maxsize];
	int result;
};
int fenzhi::falsecoin(int low, int high)
{
	int sum1=0;
	int sum2=0;
	int sum3=0;
	if (low + 1 == high)  //只有两枚硬币
	{
		if (coin[low] < coin[high])
		{
			result = low + 1;
			return result;
		}
		else
		{
			result = high + 1;
			return result;
		}
	}	
	//分治算法
	 if((high-low+1)%2==0)  //n是偶数
	{ 
		for (int i = low; i <= low+(high-low)/2; i++)
		{
			sum1 += coin[i];//前半段和
		}
		for (int j = low + (high - low) / 2+1; j <= high; j++)
		{
			sum2 += coin[j];//后半段和
		}
		if (sum1 > sum2)
		{
			result = falsecoin(low + (high - low) / 2 + 1, high); //递推后半段
			return result;
		}
		else if(sum1 < sum2)
		{
			result = falsecoin(low, low + (high - low) / 2); //递推前半段
			return result;
		}
	}
	 else  //n是奇数
	{
		for (int i = low;i<=low+(high-low)/2-1;i++)
		{
			sum1 += coin[i];   //中位数的前半段和
		}
		for (int j = low + (high - low) / 2+1; j <= high; j++)
		{
			sum2 += coin[j];   //中位数的后半段和
		}
		sum3 = coin[low + (high - low) / 2];   //中位数
		if (sum1 > sum2)      //前半段和大于后半段和
		{
			result = falsecoin(low + (high - low) / 2 + 1, high);//递推后半段
			return result;
		}
		else if (sum1 < sum2)   //前半段和小于后半段和
		{
			result = falsecoin(low, low + (high - low) / 2 - 1);//递推前半段
			return result;
		}
		if (sum1 + sum3 == sum2 + sum3)    //前半段和加中位数等于后半段和加中位数,所以中位数为目标寻找值
		{
			result = low + (high - low) / 2+1;
			return result;
		}
	}
}
void fenzhi::showresult()
{
	cout << "假币所在的位置:" << this->result << endl;
}
void text()
{
	fenzhi fz;
	cout << "输入硬币的总数目:" << endl;
	cin >> fz.num;
	cout << "请输入硬币的真假(1真/0假):" << endl;
	for (int i = 0; i < fz.num; i++)
	{
		cin >> fz.coin[i];
	}
	fz.falsecoin(0, fz.num - 1);
	fz.showresult();
}
int main()
{
	text();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风君.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值