题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1913
题意:
思路:对于每选出三个点,这三个点显然是在最后的期望中的。那么对于其他的n-3个点就不知道了。现在我们看每次选四个点,那么若四个点组成的是凹四边形,那么对答案的贡献是1( 我们说了每次选三个的话这三个是显然的,我们最后直接答案加3即可。这样的话,只有选最外边的三个点时中间才有一个点,所以对答案的贡献是1);相反,凸四边形对答案的贡献是2。这样的话,我们计算凹四边形的个数,然后用C(n,4)减去它就是凸四边形的个数设其分别为p和q个,即p+q=C(n,4)。现在我们计算p,即凹四边形的个数。枚举凹四边形的中间点,那么在过这个中间点的线同一侧的三个点构成的三角形都不包含这个点,那么用C(n-1,3)减去不包含的就是包含这个点的。最后答案为(2q+p)/C(n,3)+3。
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator-(point a)
{
return point(x-a.x,y-a.y);
}
};
point a[N],b[N];
int n;
i64 C(i64 n,i64 x)
{
if(n<x) return 0;
if(x==3) return n*(n-1)*(n-2)/6;
return n*(n-1)*(n-2)*(n-3)/24;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
void Qsort(int L,int R)
{
int i=L,j=R;
point mid=b[(L+R)/2];
while(i<=j)
{
while(cross(b[i],mid)>0) i++;
while(cross(b[j],mid)<0) j--;
if(i<=j) swap(b[i++],b[j--]);
}
if(i<R) Qsort(i,R);
if(L<j) Qsort(L,j);
}
i64 cal(int x)
{
int i,k=0;
FOR1(i,n) if(i!=x) b[++k]=a[i]-a[x];
Qsort(1,k);
FOR1(i,k) b[k+i]=b[i];
i64 ans=0;
int j=2;
point p;
FOR1(i,k)
{
p.x=-b[i].x;
p.y=-b[i].y;
while(cross(b[j],p)>0) j++;
if(j-i-1>=2) ans+=(j-i-1)*(j-i-2)/2;
}
return ans;
}
int main()
{
RD(n);
int i;
FOR1(i,n) RD(a[i].x,a[i].y);
i64 p=0;
FOR1(i,n) p+=cal(i);
i64 ans=C(n,4)*2-n*C(n-1,3)+p;
PR(1.0*ans/C(n,3)+3);
}