[jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)
题目链接:
https://jzoj.net/senior/#contest/show/2686/2
题目:

题解:
说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识
首先,若$1$号星与其他两颗星共线,那么显然新出现的 1 号星也必须在这条线上,因此可行的面积为 0 ,下文我们考虑 1 号星不与其他任意两颗星共线的情况
一个$O(n^2 log n)$的做法是枚举每一对星,$1$号星移动必然不能越过每一对星形成的直线,这样我们就可以通过半平面交解决这个问题
事实上,在这$O(n^2)$条直线中很多是冗余的,我们考虑只选出可能产生贡献的
1.考虑半平面$p_2-p_3,p_4-p_3,...,p_n-p_2$
2.令与星$p_i$极角相差不超过 $π$,且极角相差最大的星为 $p_j$ ,考虑半平面 $p_i−p_j$
然后运行半平面交即可
显然策略$1$是成立的,策略$2$画画图就很显然了
若$p_j$与$p_i$之间还有点$p_z$,那么显然$p_i-p_z$会被$p_i-p_j$遮挡掉,因为我们是要绕着原点的
特别需要注意的是我们每次添加直线要确保原点在所有直线左侧(或者在所有直线的右侧也可以,代码是左侧)
代码:
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdio>
#define il inline
using namespace std;
typedef double db; const int N=1e6+;
const db pi=acos(-1.0);
const db eps=1e-;
int n,cnt;
il int dcmp(db x) {return fabs(x)<eps?:x<?-:;}
struct point
{
db x,y;db ang;
point (db _x=,db _y=):x(_x),y(_y) {ang=atan2(y,x);}
}p[N];
bool operator < (point a,point b) {return dcmp(a.ang-b.ang)<;}
point operator + (point a,point b) {return (point){a.x+b.x,a.y+b.y};}
point operator - (point a,point b) {return (point){a.x-b.x,a.y-b.y};}
point operator * (db t,point a) {return (point){a.x*t,a.y*t};}
db det(point a,point b) {return a.x*b.y-a.y*b.x;}
struct seg
{
int a,b;db ang;
seg(int _a=,int _b=):a(_a),b(_b) {ang=atan2(p[b].y-p[a].y,p[b].x-p[a].x);};
}l[N];
bool segleft(seg x,seg y)
{
point u=p[x.b]-p[x.a];
point v=p[y.b]-p[y.a];
db tp=det(u,v);
return (tp>)||((tp==)&&det(u,p[y.a]-p[x.a])>);
}
bool operator < (seg x,seg y)
{
db o=x.ang-y.ang;
if (!dcmp(o)) return segleft(y,x);
return dcmp(o)<;
}
inline int read()
{
char ch=getchar();int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
point inter(seg x,seg y)//x与y的交点
{
point u=p[x.b]-p[x.a];
point v=p[y.b]-p[y.a];
point w=p[x.a]-p[y.a];
db d=det(w,v)/det(v,u);
return p[x.a]+d*u;
}
bool pright(seg x,point y)//点y是不是在直线x的右侧
{
point a=p[x.b]-p[x.a];
point b=y-p[x.a];
return dcmp(det(a,b))<=;
}
void add(int x,int y)//确保原点在左侧
{
if (pright(seg(x,y),point(,))) l[++cnt]=seg(y,x);
else l[++cnt]=seg(x,y);
}
int qu[N];
point a[N];
void work()
{
sort(l+,l++cnt);
int he=,ta=;
qu[++ta]=;
for (int i=;i<=cnt;i++)
if (dcmp(l[i].ang-l[i-].ang))
{
while (he<ta&&pright(l[i],inter(l[qu[ta]],l[qu[ta-]]))) --ta;
while (he<ta&&pright(l[i],inter(l[qu[he]],l[qu[he+]]))) ++he;
qu[++ta]=i;
}
while (he<ta&&pright(l[qu[he]],inter(l[qu[ta]],l[qu[ta-]]))) --ta;
if (ta-he<=)
{
puts("0.000000000");
return;
}
int tp=;
qu[he-]=qu[ta];
for (int i=he;i<=ta;i++) a[++tp]=inter(l[qu[i]],l[qu[i-]]);
a[tp+]=a[];
db res=;
for (int i=;i<=tp;i++) res+=det(a[i],a[i+]);
printf("%.10lf\n",res*0.5);
}
int main()
{
freopen("everdream.in","r",stdin);
freopen("everdream.out","w",stdout);
int NUM=read(),T=read();
while (T--)
{
n=read()-;
p[].x=1.0*read();p[].y=1.0*read();
for (int i=;i<=n;i++) p[i].x=1.0*read()-p[].x,p[i].y=1.0*read()-p[].y,p[i].ang=atan2(p[i].y,p[i].x);
cnt=;
sort(p+,p++n);
for (int i=;i<=n;i++) p[n+i]=p[i],p[n+i].ang+=*pi;
bool flag=;
for (int i=;i<=n;i++)
{
if (!dcmp(p[i].ang-p[i+].ang)) {flag=;break;}
add(i,i%n+);
point ty=(point){,};ty.ang=p[i].ang+pi;
int t=lower_bound(p+,p++*n,ty)-p;
if (t!=i+n&&!dcmp(p[t].ang-p[i].ang-pi)) {flag=;break;}
--t;
if (i!=t&&i+n!=t) add(i,(t-)%n+);
}
if (flag) {puts("0.000000000");continue;}
p[n+]=(point){-1e6,-1e6};p[n+]=(point){1e6,-1e6};
p[n+]=(point){1e6,1e6};p[n+]=(point){-1e6,1e6};
p[n+]=p[n+]-p[];p[n+]=p[n+]-p[];
p[n+]=p[n+]-p[];p[n+]=p[n+]-p[];
add(n+,n+);add(n+,n+);
add(n+,n+);add(n+,n+);
work();
}
return ;
}
[jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)的更多相关文章
- [jzoj 6101] [GDOI2019模拟2019.4.2] Path 解题报告 (期望)
题目链接: https://jzoj.net/senior/#main/show/6101 题目: 题解: 设$f_i$表示从节点$i$到节点$n$的期望时间,$f_n=0$ 最优策略就是如果从$i, ...
- [jzoj 6080] [GDOI2019模拟2019.3.23] IOer 解题报告 (数学构造)
题目链接: https://jzoj.net/senior/#main/show/6080 题目: 题意: 给定$n,m,u,v$ 设$t_i=ui+v$ 求$\sum_{k_1+k_2+...+k_ ...
- [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)
题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...
- [jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)
题目链接: https://jzoj.net/senior/#main/show/6086 题目: 题解: 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘 这样的子树 ...
- [jzoj 4528] [GDOI2019模拟2019.3.26] 要换换名字 (最大权闭合子图)
题目链接: https://jzoj.net/senior/#contest/show/2683/0 题目: 题解: 不妨枚举一个点,让两颗树都以这个点为根,求联通块要么点数为$0$,要么包括根(即联 ...
- [jzoj 6087] [GDOI2019模拟2019.3.26] 获取名额 解题报告 (泰勒展开+RMQ+精度)
题目链接: https://jzoj.net/senior/#main/show/6087 题目: 题解: 只需要统计$\prod_{i=l}^r (1-\frac{a_i}{x})$ =$exp(\ ...
- [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)
题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...
- [JZOJ 5893] [NOIP2018模拟10.4] 括号序列 解题报告 (Hash+栈+map)
题目链接: https://jzoj.net/senior/#main/show/5893 题目: 题解: 考虑暴力怎么做,我们枚举左端点,维护一个栈,依次加入元素,与栈顶元素和栈内第二个元素相同时弹 ...
- [JZOJ 5885] [NOIP2018模拟9.27] 物理实验 解题报告 (思维)
题目链接: https://jzoj.net/senior/#main/show/5885 题目: 题解: 把$a$数组按升序排序 我们可以枚举$x$,发现对于任意$x$,最优情况下$y$一定等于$x ...
随机推荐
- Windows2012R2 时间同步设置
Windows2012R2里没有了internet时间,或者Internet时间无法同步成功,都可以尝试使用如下方法. 1.打开命令提示符, 输入:gpedit.msc,打开组策略管理器 2.执行上述 ...
- 【从零开始】【Java】【2】项目最开始都有什么鬼
闲聊 刨其根知其底. 让我们从一开始就慢嚼细咽. 开始 先来看下项目都有什么: 项目结构图 pom文件图 项目结构 项目=核心代码+依赖管理文件+说明文件+IDE配套文件+外部依赖包: 核心代码:sr ...
- YoC云上芯片家族迎来新成员
Espressif 乐鑫信息科技(以下简称乐鑫科技)近日在上海召开发布会,发布其旗下最新的旗舰同时也是第二代Yun on Chip(简称YoC)云上芯片ESP32.YoC云上芯片是由YunOS牵头,联 ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(5)--使用HTML编辑控件CKEditor和CKFinder
http://www.cnblogs.com/wuhuacong/p/3780356.html Web开发上有很多HTML的编辑控件,如CKEditor.kindeditor等等,很多都做的很好,本文 ...
- 绘画软件优动漫PAINT系统要求
优动漫PAINT对运行环境有什么要求呢?目前,该软件可在Windows系统和Mac系统上使用,详细的操作运行环境如下: 操作系统:win7.win8.win10. 计算机硬件:内存必须在2GB以上,建 ...
- 添加图标:before 和 :after css中用法
#sTitle:after{ position: absolute; top: 2px; font-family: "FontAwesome"; content: "\f ...
- 【airtest】报错:requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(54, 'Connection reset by peer')),解决方法如下
1. 环境及设备:mac, xcode , iphonex 2. 最近出现一个让人费解的问题,airtest 没跑多长时间,服务就断掉,而且总是报“requests.exceptions.Connec ...
- Centos 7.2 安装和卸载 MySQL 5.7
一.背景 闲暇之余在虚拟机安装了 Centos 7.2 系统,按照 <简单安装MySQL(RPM方式)> 这篇文章安装 MySQL ,发现由于包依赖的问题安装失败,于是索性在官网查询相关文 ...
- loadrunner中的常见问题
1.Loadrunner参数化默认只显示100条数据,我们如何改变呢 E:\Program Files (x86)\HP\LoadRunner\config 2.如何突破loadrunner的Cont ...
- [luogu3952 noip2017] 逛公园 (计数dp+最短路)
传送门 Description Input Output 输出文件包含 T 行,每行一个整数代表答案. Sample Input 2 5 7 2 10 1 2 1 2 4 0 4 5 2 2 3 2 ...