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