[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 ...
随机推荐
- [Offer收割]编程练习赛40
不到一个小时AK,虽然是VP的,舒服,第一次.都简单的一比,没什么可说的. 查找三阶幻方 #pragma comment(linker, "/STACK:102400000,10240000 ...
- [Offer收割]编程练习赛33
矩阵游戏II 把每列的数字加起来当一行处理.因为每次操作两列,所以最后最多剩下一个负数.如果负数的个数是偶数,直接所有数字的绝对值加起来即可:若负数个数为奇数,把所有数的绝对值加起来减去其中最小的绝对 ...
- angular实现的tab栏切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android ToolBar自定义图标,关联DrawerLayout
Android5.0出现了一个可以代替ActionBar的控件ToolBar,使用更加灵活,一般我们使用ToolBar来和DrawerLayout配合使用,官方提供了一个开关类ActionBarDra ...
- 揭秘IPHONE X刷脸认证的技术奥秘
苹果最新发布的Iphone X具有一个全新的功能叫做刷脸认证,背后的技术其实是生物密码的更新,通过人脸识别取代了传统的指纹识别,大家肯定对这种新技术非常感兴趣,下面我们通过这篇文章为大家介绍人脸识别的 ...
- 读《Android电视机(机顶盒)初次开发的一些经验分享》后的笔记
原文: http://blog.csdn.net/tanghongchang123/article/details/52982818 一.基本命令: 1.adb connect [ip] 2. adb ...
- node linux服务器部署 centos
1下载 wget https://nodejs.org/dist/v6.9.5/node-v6.9.5-linux-x64.tar.xz 2解压 tar xvf node-v6.9.5-linu ...
- 腾讯云TrustAsia DV SSL CA证书的申请及使用
1.证书申请及管理 对于已经拥有域名及公网服务器的用户,可以通过腾讯云申请TrustAsia DV SSL CA证书,证书申请流程包含填写基本信息和域名认证两步,非常清晰和简单,没有什么需要过 ...
- wp8路线跟踪应用源码详细说明
目录 介绍 应用程序界面 定时执行 定位追踪 设置地图Pitch和Heading属性 后台位置追踪 Live Tile 总结 介绍 我从Windows Phone7 还在测试阶段的时候就开始开发了,所 ...
- boost_1_63_0在Win10上VS2015编译
装了个最新版的boost库,各种尝试,各种看网上的文章,然而就是没有编译成功.我真是哭晕在厕所. 最后还是自己老老实实啃官方文档.终于编出来了.下面记录下方法. 一·最简单的一种方法. 1.直接打开命 ...