题意:
二维明面上有n个点,设f§为绝对包含点p的n个点中的4点集合的个数,问你所有的f§之和是多少
题解:
看到平面几何我就跪了,,但是看题解这也不是一道很难的题目。对于一个点,如果有4个点五论怎么连线都无法包含这个点,那么这4个点一定在这个点的一侧,也就是说这些点和这个点的夹角不会超过180度
那么我们枚举红点的时候,对于这个点建立坐标系,也就是将其他点先算出相对于这个点的度数,之后极角排序。在枚举第一个黑点,然后找到最后一个在180度之内的黑点,那么这个区间的点选任意3个,再加上当前枚举的黑点都不能组成一个能够包含红点的四边形。于是减去这些情况
所有情况是
atan2函数就是用来计算极角
#include<bita/stdc++.h>
using namespace std;
#define ld long double
#define ll long long
const int N=2505;
ld x[N],y[N],pi=acos(-1.0L);
vector<ld>vec;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
ll ans=(ll)n*(n-1)*(n-2)*(n-3)*(n-4)/24;
for(int i=1;i<=n;i++){
vec.clear();
for(int j=1;j<=n;j++)
if(j!=i)
vec.push_back(atan2(x[j]-x[i],y[j]-y[i]));
//printf("x[i]:%f,y[i]:%f x[j]:%f,y[j]:%f ans:%f\n",x[i],y[i],x[j],y[j],atan2(y[j]-y[i],x[j]-x[i]))
sort(vec.begin(),vec.end());
int now=0;
for(int j=0;j<n-1;j++){
while(now<j+n-1){
ld d=vec[now%(n-1)]-vec[j];
if(d<0)d+=2*pi;
if(d<pi)now++;
else break;
}
ll cnt=now-j-1;
ans-=cnt*(cnt-1)*(cnt-2)/6;
}
}
printf("%lld\n",ans);
return 0;
}