参考来源
http://www.cfzhao.com/2019/07/19/2019牛客多校第一场f-random-point-in-triangle/
题意
https://ac.nowcoder.com/acm/contest/882/F
给你个三角形ABC,随便丢个点P在三角形中,问max(SABP,SACP,SBCP)的期望值乘36的结果。
思路
根据重心的性质,我们知道三个三角形被取到的概率(P点落在三个区域的面积)是一样大的。
公式为:E = 1/3E1 + 1/3E2 + 1/3E3
根据对称性,E1 = E2 = E3,所以我们只需要求一个。
这里我们求P点在四边形ADPE时三角形PBC的期望值E1
对于的三角形PBC,它能够被max()取到当且仅当它落在四边形ADGE区域,概率为1/3。要求三角形PBC在这个区域的面积的期望值,即为在这个区域取到的P点的高(P到BC的距离)的期望值,而在四边形ADGE区域中,P点的高的期望值即为四边形ADGE的重心到BC边的距离。
所以问题转化为求重心的高的期望值,求重心的高的期望值是因为这样我们能够知道三角形PBC面积的期望值与三角形ABC面积的期望值的比值,既然要求的是比值,那么重心的高的期望值的具体数值也不用算,直接求重心的高与点A的高的比值即可。
求四边形重心的方法:
- List item 连接一条对角线,使四边形被分成两个三角形
- 连接两个三角形的重心,取中点,则为四边形的重心
这里连接了对角线AG,分成了左右两个小三角形,它们的重心(中线的交点)的连线KL的中点M,即为四边形的重心。
HM:MN:NG = 1 : 2:3
所以MF:AM = 11:18
再乘36,即为22倍的三角形ABC的面积
问题转化为已知三点求三角形的面积,这里用向量叉乘即可求三角形面积,记得取绝对值,除2再乘22可能会有精度问题,这直接乘11即为答案。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll cal(ll x1, ll y1, ll x2, ll y2)//向量叉乘
{
ll ans = abs(x1 * y2 - x2 * y1);
return 11 * ans;//22倍的三角形面积,这里用叉乘求三角形的面积没有乘二分之一,所以取11倍
}
int main()
{
ll x1, y1, x2, y2, x3, y3;
while(scanf("%lld %lld %lld %lld %lld %lld", &x1, &y1, &x2, &y2, &x3, &y3) != EOF)
{
ll ans = cal(x2 - x1, y2 - y1, x3 - x1, y3 - y1);
printf("%lld\n", ans);
}
return 0;
}