牛客暑期赛第一场:Random Point in Triangle(三角形内的随机点)(数学期望)

Bobo has a triangle ABC with A(x1,y1),B(x2,y2 and C(x3,y3). Picking a point P uniformly in triangle ABC, he wants to know the expectation value E=max{SPAB,SPBC,SPCA}where SXYZ denotes the area of triangle XYZ.

波波有一个三角形,三角形三个顶点分别是A B C,在三角形均匀取一个点P,他想知道E的期望值(E是三个子三角形的面积最大值)
Print the value of 36×E It can be proved that it is always an integer.

对答案乘36,事实证明它永远是个整数

这个题的突破口在于expectation value, in,uniformly这三个单词和事件空间内的期望值公式。

换句话说,就是在事件空间里不包含边界的区域内以等概率(此为均匀之意)随机取点,求它的数学期望值。我们根据题意知道,E只能是(1/3)倍的三角形面积(不三等分,总会有一个数大于1/3)和1倍的三角形面积之间的值,那么乘以36之后就是【12S,36S)区域(S是三角形面积),由于取整数,区间变为【12S,35S】,以12S作积分下限,35S作积分上限,1作积分函数(均匀取点即等概率取点)作积分,得到E[x]=23S,即23倍三角形面积。倘若不能使三个子三角形面积相等,那么区间为【13S,35S】,作积分得到E(x)=22S,即22倍三角形面积。

同样的,利用大量随机数所得结果的平均值也可判断出期望值。具体操作方案是生成大量随机点,然后利用线性规划(对于已知三角形的三边线性表达式)判断这些点是否在三角形内,然后按照题意求出三个子三角形的面积,并求最大值。求这些样本的和,除以落在三角形内部的点数,就是答案。

#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 2000;
inline ll lldcin()
{
	ll tmp = 0, si = 1;
	char c;
	c = getchar();
	while (c > '9' || c < '0')
	{
		if (c == '-')
			si = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		tmp = tmp * 10 + c - '0';
		c = getchar();
	}
	return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
const int edges[3][2] = { -1,0,1,0,0,1 };//三角形三个顶点
ld func1(ld x, ld y)//各边的线性表达式
{
	return y-x-1;
}
ld func2(ld x, ld y)
{
	return x + y - 1;
}
ld func3(ld x, ld y)
{
	return y;
}
ld calculation(ld x1, ld y1, ld x2, ld y2, ld x3, ld y3)//三角形行列式面积公式
{
	return x1 * (y2 - y3) - y1 * (x2 - x3) + (x2*y3 - y2 * x3);
}
int DETERMINATION()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	ld area =fabs(calculation(1, 0, 0, 1, -1, 0))/2.0;
	ld sum = 0,cnt=0;
	ld mx1=0, mx2=0, mn1=0, mn2=0;
	for (int i = 1; i <= 1000000; i++)
	{
		ld x = ((double(rand()) / RAND_MAX )* 2) - 1;
		ld y =((double(rand()) / RAND_MAX) * 2) - 1;//生成随机实数,范围为【-1,1】
		//mx1 = max(x, mx1), mx2 = max(y, mx2), mn1 = min(mn1, x), mn2 = min(y, mn2);
		//cout << x << " " << y << endl;
		if (func1(x, y) < 0 && func2(x, y) < 0 && func3(x, y) > 0)
		{
			cnt++;
			ld tmp1, tmp2, tmp3;
			tmp1 = fabs(calculation(x, y, 1, 0, -1, 0))/2;
			tmp2 = fabs(calculation(x, y, 0, 1, -1, 0))/2;
			tmp3 = fabs(calculation(x, y, 0, 1, 1, 0))/2;//求子三角形面积
			ld tmpans = max(max(tmp1, tmp2), max(tmp2, tmp3));
			sum += tmpans;
		}
	}
	//cout << mx1 << " " << mx2 << " " << mn1 << " " << mn2 << endl;
	sum /= cnt;//求均值
	cout << (sum*36/ area) << endl;
	return 0;
}

 

posted @ 2019-07-28 23:35  完全墨染的樱花  阅读(421)  评论(0)    收藏  举报