如果四个点不能组成凸四边形,则必然是其中三个点组成一个三角形,另一个点在该三角形内部。于是我们可以O(n)枚举一个点作为内部中心,试图从其他的点里选出三个来,组成三角形把它包围住,看看有多少种可能的选择。继续观察发现,如果三个点不能圈住中心点,则必然是存在一条通过中心点的直线,使得这三点都在直线的同侧。于是我们可以把所有点(除了中心点)按极角排序,然后线性转圈扫描一下就可以统计出来了。总的复杂度是O(n^2*logn)
typedef long long LL ;
LL C(int n , int k){
if(k > n) return 0 ;
if(k == 1) return (LL)n ;
if(k == 2) return (LL)n * (LL)(n-1) / 2 ;
if(k == 3) return (LL)n * (LL)(n-1) * (LL)(n-2) / 6 ;
if(k == 4) return (LL)n * (LL)(n-1) * (LL)(n-2) * (LL)(n-3) / 24 ;
}
struct Point{
double x , y ;
double dist(Point o){
return sqrt((x-o.x)*(x-o.x)+(y-o.y)*(y-o.y)) ;
}
void read(){
scanf("%lf%lf" , &x , &y) ;
}
};
const double PI = acos(-1.0) ;
Point po[1008] ;
double x[2008] ;
int main(){
LL sum ;
int t , n , i , j , k ;
cin>>t ;
while(t--){
cin>>n ;
for(i = 1 ; i <= n ; i++) po[i].read() ;
sum = C(n , 4) ;
for(i = 1 ; i <= n ; i++){
k = 0 ;
for(j = 1 ; j <= n ; j++){
if(i == j) continue ;
x[k++] = acos((po[j].x - po[i].x) / po[i].dist(po[j])) ;
if(po[j].y < po[i].y) x[k-1] = 2*PI - x[k-1] ;
}
sort(x , x+k) ;
for(j = 0 ; j < k ; j++) x[k+j] = x[j] + 2*PI ;
LL s = C(n-1 , 3) ;
for(int a = 0 , b = 1 ; a < k && b < 2*k ; a++){
while(x[b] - x[a] < PI) b++ ;
if(b-a-1 >= 2) s -= C(b-a-1 , 2) ;
}
sum -= s ;
}
cout<<sum<<endl ;
}
return 0 ;
}