[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 }