1913: [Apio2010]signaling 信号覆盖

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 1232  Solved: 506
[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

Solution

这题的思路还是很巧妙的QwQ

首先要是枚举点,复杂度是$O(N^4)$的,而且难以进一步优化。

这里保证四点不共圆,所以可以考虑一下从多边形对答案的贡献的入手。

对于一个凸多边形,它对答案的贡献是$2$,即以一组对角和$>\pi$的两个点中的任意一个和另外两个点做圆,一定能覆盖另一个点。

对于一个凹多边形,它对答案的贡献只有$1$,即以靠外三个点做圆可以覆盖凹进去的那个点。

所以可以得到答案$ans=3+\frac {2*cnt_{凸}+1*cnt_{凹}} {C^{N}_{3}}$

然后就是如何快速的求出凸多边形和凹多边形的数量了。

因为这里保证了不存在三点共线,考虑$O(N^2)$的枚举两个点组成的一条直线,算出直线两边的两个点和直线上两点组成多边形的情况。

对于直线两边的点数量分别是$a$和$b$,就对答案加入$C^{a}_{2}$和$C^{b}_{2}$,这里利用极角排序,可以利用单调性做到直线旋转时的均摊$O(1)$的复杂度。

然后考虑这样统计出来的是什么,对于一个凸多边形,利用这样的方式,会被统计四次,对于一个凹多边形,这样会统计三次,所以这样的答案就是$4*cnt_{凸}+3*cnt_{凹}$

然后减掉$2*(cnt_{凸}+cnt_{凹})=2*cnt_{总}=2*C^{n}_{4}$,就可以得到$2*cnt_{凸}+1*cnt_{凹}$。同时就可以得到答案。

所以总复杂度是$O(N^2)$就得到解决。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define Pi acos(-1.0)
#define MAXN 2010 int N,tot;
struct Point{
int x,y;
}P[MAXN];
double k[MAXN<<1],ans; inline double C(int n,int m)
{
double re=1;
for (int i=n-m+1; i<=n; i++) re=re*i;
for (int i=1; i<=m; i++) re=re/i;
return re;
} int main()
{
N=read();
for (int i=1; i<=N; i++) P[i].x=read(),P[i].y=read(); for (int i=1; i<=N; i++) {
tot=0;
for (int j=1; j<=N; j++)
if (i!=j) k[++tot]=atan2(P[j].x-P[i].x,P[j].y-P[i].y);
sort(k+1,k+tot+1);
for (int j=1; j<=tot; j++) k[tot+j]=k[j]+2.0*Pi;
for (int j=1,now=1; j<=tot; j++) {
while (k[now]-k[j]<Pi) now++;
int cnt=now-j-1;
ans+=C(cnt,2);
}
} ans-=C(N,4)*2; printf("%.6lf\n",ans/C(N,3)+3.0);
return 0;
}

  

【BZOJ-1913】signaling信号覆盖 极角排序 + 组合的更多相关文章

  1. [BZOJ 1913] signaling 信号覆盖

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1913 TIP:(注意,这题只能输出6位才能过,7位都不行wtf?) Algorithm: ...

  2. bzoj1913[Apio2010]signaling 信号覆盖 计算几何

    1913: [Apio2010]signaling 信号覆盖 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1583  Solved: 646[Subm ...

  3. bzoj 1913: [Apio2010]signaling 信号覆盖【旋转卡壳(?)】

    参考:https://blog.csdn.net/qpswwww/article/details/45334033 讲的很清楚 做法比较像旋转卡壳但是具体是不是我也不清楚.. 首先知道只要求出每种方案 ...

  4. [CF1025F]Disjoint Triangles[极角排序+组合计数]

    题意 平面上有 \(n\) 个点,选出六个点构成两个三角形,问有多少种构造方式使得两个三角形没有交集. \(n\leq 2000\) 分析 枚举连接两个三角形的两个顶点,同时能够将两个三角形划分在直线 ...

  5. BZOJ 1132 [POI2008]Tro(极角排序)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1132 [题目大意] 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和(N&l ...

  6. bzoj 5099 [POI2018]Pionek 计算几何 极角排序

    [POI2018]Pionek Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 269  Solved: 80[Submit][Status][Disc ...

  7. 【BZOJ】1913: [Apio2010]signaling 信号覆盖(计算几何+计数)

    题目 传送门:QWQ 分析 人类智慧题,不会做...... 详细题解1      详细题解2 总体思路是考虑四边形 讨论凹四边形凸四边形,最后加一个单调性优化省掉个$ O(n) $ 代码 代码感觉好短 ...

  8. 【bzoj1913】 Apio2010—signaling 信号覆盖

    http://www.lydsy.com/JudgeOnline/problem.php?id=1913 (题目链接) 题意 给出一个平面上n个点,求任选3个点画一个圆所包含的点的期望值. Solut ...

  9. bzoj1913: [Apio2010]signaling 信号覆盖

    传送门 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #includ ...

随机推荐

  1. git高清技能图

    ----

  2. BSGS 算法

    求解 A^x ≡ B mod C  C是质数 的最小非负整数解 证明:A^x ≡ A^(x%φ(C)) mod C A^(x%φ(C))  ≡ A^(x-k*φ(C)) ≡ (A^x)/ A^(k*φ ...

  3. .NET面试题系列(五)数据结构(Array、List、Queue、Stack)及线程安全问题

    常用数据结构的时间复杂度 如何选择数据结构 Array (T[]) 当元素的数量是固定的,并且需要使用下标时. Linked list (LinkedList<T>) 当元素需要能够在列表 ...

  4. 作业:JavaScript(数组篇-poker)给我的徒弟出个题。。。记得早点写完,然后大家3人可以早点打牌了

    吐槽一下:“今天实际上我左思右想,写个什么东西好呢!手上的笔转了半天....最后还是给自己留点余地!看着他们什么酒店管理系统,呼叫中心系统之类的....简直是把自己固定死了!感觉一撸到底的感觉!!!我 ...

  5. js深复制

    一般来讲深复制主要是为了复制js对象中的引用类型,引用类型在普通的赋值操作下相当于是引用,修改复制对象也会影响原对象,简单的方法的话可以使用JSON.parse(JSON.stringify(obj) ...

  6. F. Ivan and Burgers(线性基,离线)

    题目链接:http://codeforces.com/contest/1100/problem/F 题目大意:首先输入n,代表当前有n个数,然后再输入m,代表m次询问,每一次询问是询问区间[l,r], ...

  7. Python 入门基础6 --字符编码、文件操作1

    今日内容: 1.字符编码 2.字符与字节 3.文件操作 一.字符编码 了解: cpu:将数据渲染给用户 内存:临时存放数据,断电消失 硬盘:永久存放数据,断电后不消失 1.1 什么是编码? 人类能够识 ...

  8. win10下安装MinGW-w64 - for 32 and 64 bit Windows

    对于不经常使用c语言的同学来说,只需要安装MinGW-w64 - for 32 and 64 bit Windows,就可以使用GCC在命令行对c源码进行编译. 首先打开命令行检查自己是否已经安装了g ...

  9. PHP回调函数及匿名函数概念与用法详解

    1.回调函数 PHP的回调函数其实和C.Java等语言的回调函数的作用是一模一样的,都是在主线程执行的过程中,突然跳去执行设置的回调函数: 回调函数执行完毕之后,再回到主线程处理接下来的流程 而在ph ...

  10. 浅谈SpringMVC

    M--模型(实体vo[视图对象]与页面对面) V--视图(JSP,,velocity,FreeMarker,html,thymeleaf) C--控制器(servlet,if语句控制M数据跳转到V进行 ...