[BZOJ1913][APIO2010]信号覆盖(计算几何+计数)
1913: [Apio2010]signaling 信号覆盖
Time Limit: 20 SecMemory Limit: 64 MBSubmit: 1658Solved: 672
[Submit][Status][Discuss]
Description
Input
输入第一行包含一个正整数 n, 表示房子的总数。接下来有 n 行,分别表示每一个房子的位置。对于 i = 1, 2, .., n, 第i 个房子的坐标用一对整数 xi和yi来表示,中间用空格隔开。
Output
输出文件包含一个实数,表示平均有多少个房子被信号所覆盖,需保证输出结果与精确值的绝对误差不超过0.01。
Sample Input
4
0 2
4 4
0 0
2 0
Sample Output
3.500
HINT
3.5, 3.50, 3.500, … 中的任何一个输出均为正确。此外,3.49, 3.51,
3.499999,…等也都是可被接受的输出。
【数据范围】
100%的数据保证,对于 i = 1, 2, .., n, 第 i 个房子的坐标(xi, yi)为整数且
–1,000,000 ≤ xi, yi ≤ 1,000,000. 任何三个房子不在同一条直线上,任何四个房子不
在同一个圆上;
40%的数据,n ≤ 100;
70%的数据,n ≤ 500;
100%的数据,3 ≤ n ≤ 1,500。
Source
场上绝对想不到系列。https://blog.csdn.net/regina8023/article/details/45556321
1 #include<cmath> 2 #include<cstdio> 3 #include<algorithm> 4 #define rep(i,l,r) for (int i=l; i<=r; i++) 5 typedef long long ll; 6 using namespace std; 7 8 const double Pi=acos(-1.); 9 const int N=2010; 10 struct P{ double x,y; }p[N]; 11 double a[N<<1]; 12 int n; 13 14 ll C(int n,int m){ 15 ll ans=1; 16 rep(i,1,m) ans=1ll*ans*(n-i+1); 17 rep(i,2,m) ans/=i; 18 return ans; 19 } 20 21 int main(){ 22 freopen("signaling.in","r",stdin); 23 freopen("signaling.out","w",stdout); 24 scanf("%d",&n); ll t=0; 25 rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y); 26 rep(i,1,n){ 27 int tot=0; 28 rep(j,1,n) if (j!=i){ 29 a[++tot]=atan2(p[j].y-p[i].y,p[j].x-p[i].x); 30 if (a[tot]<0) a[tot]+=Pi*2; 31 } 32 sort(a+1,a+n); 33 rep(j,1,n-1) a[n-1+j]=a[j]+2*Pi; 34 ll x=0; int now=1; 35 rep(j,1,n-1){ 36 while (now<(n-1)*2 && a[now+1]-a[j]<Pi) now++; 37 if (now-j>1) x=x+C(now-j,2); 38 } 39 t=t+C(n-1,3)-x; 40 } 41 double ans=(double)(t+(C(n,4)-t)*2)/C(n,3)+3; 42 printf("%.6lf\n",ans); 43 return 0; 44 }