对于每一个点,它与原点的连线将平面划分为两个半平面,我们统计连线的逆时针方向的半平面中的点的个数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 . |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步