hdu 3629

点击打开链接


 
 
如果四个点不能组成凸四边形,则必然是其中三个点组成一个三角形,另一个点在该三角形内部。
于是我们可以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 ;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值