算法基本思想

1.分治算法,递归找出假硬币

//分治算法,递归找出假硬币,只有一枚假硬币
#include <iostream>
#include <vector>

using namespace std;

#define  COINSIZE 10
int g_count = 0;
int falseCoin(vector <int> coin, int begPosi, int endPosi);//函数

int main()
{
	int falsePosi = 0, flasePosiFind = 0;
	vector <int> coin(COINSIZE, 1);
	cout << "设置假硬币位置:(共有" << COINSIZE << "枚硬币,位置从0开始计算)" << endl;
	cin >> falsePosi;							//输入为falsePosi,在数组中的序号为falsePosi-1
	coin[falsePosi] = 0;
	cout << "此时硬币序列为:(真为1,假为0)" << endl;
	for (auto c : coin)
	{
		cout << c << " ";
	}

	//开始找假硬币,位置为0 ~ COINSIZE-1
	cout << endl << "利用分治法寻找假硬币" << endl;
	flasePosiFind = falseCoin(coin, 0, COINSIZE - 1);
	cout << "可知假硬币位置为:" << flasePosiFind << endl;
	system("pause");
	return 0;
}

int falseCoin(vector <int> coin,int begPosi, int endPosi)
{
	cout << "第" << g_count++ << "次调用函数" << endl;

	//根据硬币数量是奇数还是偶数区分
	int sumLeft = 0; // 左侧硬币重量之和
	int sumRight = 0; // 右侧硬币重量之和
	if (begPosi == endPosi + 1) //最后
	{
		if (coin[begPosi] < coin[endPosi])
		{
			return begPosi; //较轻的为假币
		}
		else
			return endPosi; //较轻的为假币
	}
	
	if ( (endPosi-begPosi)%2 ) //(endPosi-begPosi)%2 为真,代表硬币总数为偶数;begPosi从0开始计数
	{
		int v1, v2;
		for (v1 = begPosi; v1 <= begPosi + (endPosi - begPosi + 1) / 2 - 1; ++v1)
		{
			sumLeft = sumLeft + coin[v1];
		}
		for (v2 = endPosi - ((endPosi - begPosi + 1) / 2 - 1); v2 <= endPosi; ++v2)
		{
			sumRight = sumRight + coin[v2];
		}
		if (sumLeft < sumRight)
		{
			return falseCoin(coin, begPosi, begPosi + (endPosi - begPosi + 1) / 2 - 1);//左边重
		}
		else if (sumLeft > sumRight)
		{
			return falseCoin(coin, endPosi - ((endPosi - begPosi + 1) / 2 - 1), endPosi);//右边重
		}
		else
		{
			cout << "两边一样重" << endl;
			getchar();
			return -1;
			exit(0);
		}
	}

	if ((endPosi - begPosi) % 2 + 1)//(endPosi-begPosi)%2+1 为真,代表硬币总数为奇数;begPosi从0开始计数
	{
		int v1, v2;
		for ( v1 = begPosi; v1 <= begPosi + (endPosi - begPosi) / 2 - 1; ++v1)
		{
			sumLeft = sumLeft + coin[v1];//左边
		}
		for (v2 = endPosi - ((endPosi - begPosi) / 2 - 1); v2 <= endPosi; ++v2)
		{
			sumRight = sumRight + coin[v2];//右边
		}
		if (sumLeft == sumRight)
		{
			return begPosi + (endPosi - begPosi) / 2;//返回中间的那个值
		}
		if (sumLeft < sumRight)
		{
			return falseCoin(coin, begPosi, begPosi + (endPosi - begPosi) / 2 - 1);
		}
		if (sumLeft > sumRight)
		{
			return falseCoin(coin, endPosi - ((endPosi - begPosi) / 2 - 1), endPosi);
		}
	}
}

2.蒙特卡洛算法计算圆周率

// 通过统计第一象限中圆内的点数,近似得到圆周率的数值

#include <iostream>
#include <ctime>

using namespace std;
double MontePI(int monteNum);

int main()
{
	int monteNum = 0;
	double simuPI ; //圆周率
	cout << "输入蒙特卡洛仿真次数" << endl;
	cin >> monteNum;
	srand((unsigned)time(NULL));
	simuPI = MontePI(monteNum);
	cout << "经过多次蒙特卡洛模拟,得到圆周率近似值为:" << simuPI << endl;
	system("pause");
	return 0;
}

//蒙特卡洛概率算法计算圆周率
double MontePI(int monteNum)
{
	double x, y;
	double PI = 0;
	int effTime = 0;
	for (int i = 0; i <= monteNum; ++i)
	{
		x = (double)rand() / RAND_MAX;
		y = (double)rand() / RAND_MAX;
		if ((x*x + y*y) <= 1)
		{
			++effTime; //有效次数
		}
	}
	PI = 4.0*effTime / monteNum;
	return PI;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值