1 条题解
-
0
自动搬运
来自洛谷,原作者为

Hammer_cwz_77
**搬运于
2025-08-24 21:50:58,当前版本为作者最后更新于2017-11-03 19:55:53,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
N^4的算法很好想,枚举三个点组成一个圆,再枚举一个点判断点是否在圆内,统计输出就可以了,但这样显然只能拿到40分。
对于任意4个点,组成的图形只有两种,一种是凸四边形,一种是凹四边形,即一个点在另外三个点组成的三角形内。
对于凸四边形,必有一组对角大于180°,此时这组对角所对应的顶点必然在另外三个点组成的圆中,所以每个凸四边形对于总的答案贡献两个点。
对于凹四边形,设D在三角形ABC内,那么只有D在三角形ABC组成的圆中,A,B和C都不在另外三个点的圆中,所以凹四边形对总的答案贡献一个点。
由于总的四边形个数一定,我们只需要求出凹四边形的个数。
首先枚举凹点D,以D作为极点,x轴正半轴为极轴进行极角排序,对于一个合法的三角形ABC,过D的任意一条直线都不能使三个点在D的同一侧,这样我们就用总的三角形个数C(n-1,3)来减去同一侧的三角形个数。这样枚举一个点A,找到A到C的角小于180°的最远点C,设A的编号为i,C的编号为j,那么此时在一侧的三角形个数为C(j-i,2),由于C对于每一个A是单调的,所以每一次的复杂度均为n,总的复杂度就是n^2,加上排序的复杂度,总复杂度为n^2logn。
Code
program test3; uses math; var x,y:array[0..1500]of extended; p,q:array[0..3000]of extended; i,j,m,k:longint; tot,sum1,sum2,sum,now,n:int64; ans:extended; procedure kp(l,r:longint); var i,j:longint; x,y:extended; begin i:=l;j:=r; x:=p[(l+r)shr 1]; repeat while p[i]<x do inc(i); while p[j]>x do dec(j); if i<=j then begin y:=p[i]; p[i]:=p[j]; p[j]:=y; inc(i); dec(j); end; until i>j; if l<j then kp(l,j); if i<r then kp(i,r); end; begin readln(n); for i:=1 to n do readln(x[i],y[i]); tot:=n*(n-1)*(n-2)div 6; for k:=1 to n do begin p[k]:=0; for i:=1 to n do begin if i=k then continue; q[i]:=(x[i]-x[k])/sqrt(sqr(x[i]-x[k])+sqr(y[i]-y[k])); p[i]:=arccos(q[i]); if y[i]<y[k] then p[i]:=2*pi-p[i]; end; kp(1,n); for i:=2 to n do p[i+n-1]:=p[i]; j:=2; now:=0; for i:=2 to n do begin while (((p[j+1]-p[i]<=pi)and(p[j+1]>=p[i]))or(p[j+1]-p[i]<-pi))and(j<i+n-2) do inc(j); now:=now+(j-i)*(j-i-1)div 2; end; sum:=sum+(n-1)*(n-2)*(n-3)div 6-now; end; sum1:=sum; sum2:=n*(n-1)*(n-2)*(n-3)div 24-sum1; sum:=sum1+sum2*2+tot*3; ans:=sum/tot; writeln(ans:0:6); end.
- 1
信息
- ID
- 1831
- 时间
- 2000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者