Description
给出一个二维平面三角形的三个顶点坐标,问在该三角形内随机选取 n n 个点,他们形成的凸包的顶点数量期望值
Input
输入三个点的横纵坐标以及点数 n n
Output
输出凸包顶点的期望值
Sample Input
0 0
1 0
2 1
3
Sample Output
3.000000000000
Solution
n n 很小,本地暴力撒点求期望即可,发现规律为
Code
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 15
const double eps=1e-8;
const double PI=acos(-1.0);
struct Point
{
double x,y;
double k;
Point(){}
Point(double _x,double _y)
{
x=_x;y=_y;
}
Point operator -(const Point &b)const
{
return Point(x-b.x,y-b.y);
}
double operator ^(const Point &b)const
{
return x*b.y-y*b.x;
}
double operator *(const Point &b)const
{
return x*b.x+y*b.y;
}
};
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
else return 1;
}
double dist(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Point list[maxn];
int Stack[maxn],top;
//相对于list[0]的极角排序
bool _cmp(Point p1,Point p2)
{
double tmp=(p1-list[0])^(p2-list[0]);
if(sgn(tmp)>0)return true;
else if(sgn(tmp)==0&&sgn(dist(p1,list[0])-dist(p2,list[0]))<=0)return true;
else return false;
}
int Graham(int n)
{
Point p0;
int k=0;
p0=list[0];
//找最下边的一个点
for(int i=1;i<n;i++)
{
if((p0.y>list[i].y)||(p0.y==list[i].y&&p0.x>list[i].x))
{
p0=list[i];
k=i;
}
}
swap(list[k],list[0]);
sort(list+1,list+n,_cmp);
if(n==1)
{
top=1;
Stack[0]=0;
return 1;
}
if(n==2)
{
top=2;
Stack[0]=0;
Stack[1]=1;
return 2;
}
Stack[0]=0;
Stack[1]=1;
top=2;
for(int i=2;i<n;i++)
{
while(top>1&&sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]]))<=0)
top--;
Stack[top++]=i;
}
return top;
}
void random(int n)
{
for(int i=0;i<n;i++)
{
double x=rand(),y=rand();
x/=RAND_MAX,y/=RAND_MAX;
if(x<y)swap(x,y);
list[i].x=x,list[i].y=y;
}
}
int main()
{
/*
for(int n=3;n<=10;n++)
{
srand(time(0));
int cnt=1e7;
double p=cnt,ans=0;
while(cnt--)
{
random(n);
ans+=Graham(n);
}
printf("n=%d %.5f\n",n,ans/p);
}*/
int a;
for(int i=1;i<=6;i++)scanf("%d",&a);
int n;
scanf("%d",&n);
double ans=3;
for(int i=3;i<n;i++)ans+=2.0/i;
printf("%.5f\n",ans);
return 0;
}