BZOJ1914

对于每一个点,它与原点的连线将平面划分为两个半平面,我们统计连线的逆时针方向的半平面中的点的个数N,
这N个点与这个点构成的N(N-1)/2个三角形都是不包含原点的.最后只要用总个数减去这些三角形的和就是答案.
统计过程极角排序后可以做到O(N).

 

/************************************************************** 
    Problem: 1914
    User: exponent 
    Language: Pascal 
    Result: Accepted 
    Time:260 ms 
    Memory:1008 kb 
****************************************************************/ 
  
type  point=record
      x,y:longint; 
end; 
const maxn=100001; 
var   p:array[0..maxn] of point; 
      ans,tmp,count:int64; 
      n,i,j:longint; 
  
  
      function cross(a,b:point):int64; 
      begin
            exit(int64(a.x)*int64(b.y)-int64(b.x)*int64(a.y)); 
      end; 
  
      function cmp(a,b:point):boolean;   //return angle(a)<angle(b) 
      begin
            if (a.y>0)and(b.y<=0) then exit(true); 
            if (b.y>0)and(a.y<=0) then exit(false); 
            if cross(a,b)>0 then exit(true); 
            exit(false); 
      end; 
  
      procedure sort(l,r:longint); 
      var   i,j:longint; 
            mid,temp:point; 
      begin
            i:=l; j:=r; 
            mid:=p[(l+r)>>1]; 
            while i<=j do
            begin
                  while cmp(p[i],mid) do inc(i); 
                  while cmp(mid,p[j]) do dec(j); 
                  if i<=j then
                  begin
                        temp:=p[i]; 
                        p[i]:=p[j]; 
                        p[j]:=temp; 
                        inc(i); dec(j); 
                  end; 
            end; 
            if i<r then sort(i,r); 
            if j>l then sort(l,j); 
      end; 
  
  
begin
      readln(n); 
      for i:=1 to n do readln(p[i].x,p[i].y); 
  
      sort(1,n); 
  
      j:=1; 
      count:=0; 
      for i:=1 to n do
      begin
            while cross(p[i],p[j mod n+1])>=0 do
            begin
                  if j mod n+1=i then break; 
                  j:=j mod n+1; 
                  inc(count); 
            end; 
            inc(tmp,count*(count-1)>>1); 
            dec(count); 
      end; 
      ans:=int64(n)*int64(n-1) div 2*int64(n-2) div 3; 
      writeln(ans-tmp); 
end.

转载于:https://www.cnblogs.com/exponent/archive/2011/08/24/2152370.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值