[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 ...
随机推荐
- IEnumerable ICollection IList
- 腾讯云TrustAsia DV SSL CA证书的申请及使用
1.证书申请及管理 对于已经拥有域名及公网服务器的用户,可以通过腾讯云申请TrustAsia DV SSL CA证书,证书申请流程包含填写基本信息和域名认证两步,非常清晰和简单,没有什么需要过 ...
- java加密解密算法位运算
一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...
- Windows各种计时器
(一):OnTimer类 1.打开对应对话框的类向导ClassWizard. 2.在消息映射MessageMaps中添加消息Message:WM_TIMER. 3.程序代码中将自动添加函数OnTime ...
- bootstrap初用新得1
## 基本准备 1. 首先把相关软件窗口规划好,对于我的喜好,我喜欢把除了浏览器外的其他软件分为左右两个半屏.左边和右边很多软件之间是需要配合使用的: * 左边: scss文件,ps的guid ...
- nutz 自定义sql的使用
虽然提供了Cnd,但是用起来是觉得有点不方便,然后就直接编写Sql语句.nutz提供了一些方法. Nutz.Dao 的自定义 SQL 部分的解决方案是: // 不推荐使用 用户可以硬编码 SQL 语句 ...
- git基础讲解
idea :https://blog.csdn.net/autfish/article/details/52513465 eclipse:https://blog.csdn.net/yang57266 ...
- 移动前端头部标签(HTML5 head meta)转载
移动web页面头部书写 字数2516 阅读1128 评论0 喜欢30 HTTP 标题信息(http-equiv) 和页面描述信息(name) http-equiv:该枚举的属性定义,可以改变服务器和用 ...
- node——通过express模拟Apache实现静态资源托管
1.express中处理静态资源的函数 创建一个app.js作为入口文件,创建一个public文件夹作为静态资源文件夹 var app=express();var fn=express.static( ...
- asyncio 自动跳出长时间堵塞的 task
https://www.cnblogs.com/ywhyme/p/10660411.html 的升级版 可以知道当前是卡在哪一个 task 甚至是多少行 import asyncio import o ...