[NOI.AC省选模拟赛3.31] 星辰大海 [半平面交]
题面
思路
懒得解释了......也是比较简单的结论
但是自己看到几何就退缩了......
下周之内写一个计算几何的学习笔记!
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define eps 1e-14
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
/*
Calculating the intersection of two segments:
method 1: Brute force implemention -> get 4 equations, take the position of target point as the unknown factor
method 2: Solve using vector -> the 'x-multiple' of two planary vectors is the SIGNED area of the paralellogram formed by them.
ALWAYS MIND the sign before the area (refer to function cross(seg,seg) for further detail)
*/
int T,N,n,m;
inline int sign(const long double &d){
if(d>eps) return 1;
if(d<-eps) return -1;
return 0;
}
struct p{
long double x,y;
p(long double xx=0.0,long double yy=0.0){x=xx;y=yy;}
}rt[1000010];
inline p operator *(const p &a,const long double &b){return p(a.x*b,a.y*b);}
inline long double operator *(const p &a,const p &b){return a.x*b.y-a.y*b.x;}//'x-multiple' of planary vector
inline p operator -(const p &a,const p &b){return p(a.x-b.x,a.y-b.y);}
inline p operator +(const p &a,const p &b){return p(a.x+b.x,a.y+b.y);}
struct ele{
p a;long double k;
}lis[1000010];
struct seg{
p a,b;long double k;
seg(p aa=p(),p bb=p(),long double kk=0.0){a=aa;b=bb;k=kk;}
}a[1000010],q[1000010];
inline long double getk(const p &a){return atan2l(a.y,a.x);}//get the k-value of a pair<long double,dobule>
inline bool cmp(const ele &l,const ele &r){return l.k<r.k;}
inline bool operator <(const seg &l,const seg &r){return l.k<r.k;}//sort according to k
inline p cross(const seg &x,const seg &y){//calculate the intersection using planary vector
long double v1=(x.a-y.b)*(x.b-y.b);
long double v2=(x.a-y.a)*(x.b-y.a);
long double c=v1/(v1-v2);
p re=(y.b+((y.a-y.b)*c));
return re;
}
inline bool right(const p &x,const seg &y){//determine if x is to the right of y
return ((x-y.a)*(x-y.b))>=0;
}
inline long double solve(){
int i,head=1,tail=0,flag;long double re=0;
sort(a+1,a+m+1);
for(i=1;i<=m;i++){
flag=0;
while(head<=tail&&(!sign(a[i].k-q[tail].k))){//get rid of segments at same k
if((q[tail].a-a[i].a)*(q[tail].a-a[i].b)>=0) tail--;//if old one is to the right of current one, delete it
else{flag=1;break;}//or else, the current one shall be deleted
}
if(flag) continue;
while(head<tail&&right(rt[tail],a[i])) tail--;//check if the intersection is to the right, if so delete the foremost/backmost segment
while(head<tail&&right(rt[head+1],a[i])) head++;
q[++tail]=a[i];
if(head<tail) rt[tail]=cross(q[tail-1],q[tail]);
}
while(head<tail&&right(rt[tail],q[head])) tail--;
while(head<tail&&right(rt[head+1],q[tail])) head++;
rt[head]=rt[tail+1]=cross(q[head],q[tail]);//mind that the first and last points are adjacent
for(i=head;i<=tail;i++){
re+=rt[i]*rt[i+1];
}
return re;
}
const long double pi=acosl(-1.0);
const p ur(1e6,1e6);
const p ul(-1e6,1e6);
const p dr(1e6,-1e6);
const p dl(-1e6,-1e6);
const seg rr(ur,dr,-pi*0.5);
const seg dd(dr,dl,pi);
const seg ll(dl,ul,pi*0.5);
const seg uu(ul,ur,0);
int main(){
N=read();T=read();int flag,i,j;
while(T--){
n=read();
m=0;
a[++m]=rr;a[++m]=dd;a[++m]=ll;a[++m]=uu;
for(i=1;i<=n;i++){
lis[i].a.x=read();
lis[i].a.y=read();
}
for(i=2;i<=n;i++){
lis[i].k=getk(lis[i].a-lis[1].a);
}
sort(lis+2,lis+n+1,cmp);
for(i=2;i<=n;i++){
lis[i+n-1]=lis[i];
lis[i+n-1].k+=2.0*pi;
}
flag=1;j=2;
for(i=2;i<=n;i++){
j=max(i,j);
while(lis[j+1].k-lis[i].k<pi+eps) j++;
if((!sign(lis[i+1].k-lis[i].k))||(!sign(lis[i].k+pi-lis[j].k))){
flag=0;puts("0");break;
}
if(j!=i) a[++m]=seg(lis[j].a,lis[i].a,getk(lis[i].a-lis[j].a));
if(lis[i+1].k-lis[i].k<pi+eps) a[++m]=seg(lis[i+1].a,lis[i].a,getk(lis[i].a-lis[i+1].a));
}
if(flag) printf("%.9lf\n",(double)solve()*0.5);
}
}
[NOI.AC省选模拟赛3.31] 星辰大海 [半平面交]的更多相关文章
- [NOI.AC省选模拟赛3.31] 附耳而至 [平面图+最小割]
题面 传送门 思路 其实就是很明显的平面图模型. 不咕咕咕的平面图学习笔记 用最左转线求出对偶图的点,以及原图中每个边两侧的点是谁 建立网络流图: 源点连接至每一个对偶图点,权值为这个区域的光明能量 ...
- NOI.AC省选模拟赛第一场 T1 (树上高斯消元)
link 很容易对于每个点列出式子 \(f_{x,y}=(f_{x,y-1}+f_{x,y}+f_{x,y+1}+f_{x+1,y})/4\)(边角转移类似,略) 这个转移是相互依赖的就gg了 不过你 ...
- [NOI.AC省选模拟赛3.30] Mas的童年 [二进制乱搞]
题面 传送门 思路 这题其实蛮好想的......就是我考试的时候zz了,一直没有想到标记过的可以不再标记,总复杂度是$O(n)$ 首先我们求个前缀和,那么$ans_i=max(pre[j]+pre[i ...
- [NOI.AC省选模拟赛3.23] 染色 [点分治+BFS序]
题面 传送门 重要思想 真的是没想到,我很久以来一直以为总会有应用的$BFS$序,最终居然是以这种方式出现在题目中 笔记:$BFS$序可以用来处理限制点对距离的题目(综合点分树使用) 思路 本题中首先 ...
- [NOI.AC省选模拟赛3.23] 集合 [数学]
题面 传送门 一句话题意: 给定$n\leq 1e9,k\leq 1e7,T\leq 1e9$ 设全集$U=\lbrace 1,2,3,...n\rbrace $,求$(min_{x\in S}\lb ...
- [noi.ac省选模拟赛]第12场题解集合
题目 比赛界面. T1 数据范围明示直接\(O(n^2)\)计算,问题就在如何快速计算. 树上路径统计通常会用到差分方法.这里有两棵树,因此我们可以做"差分套差分",在 A 树上对 ...
- [noi.ac省选模拟赛]第10场题解集合
题目 比赛界面. T1 不难想到,对于一个与\(k\)根棍子连接的轨道,我们可以将它拆分成\(k+1\)个点,表示这条轨道不同的\(k+1\)段. 那么,棍子就成为了点与点之间的边.可以发现,按照棍子 ...
- [noi.ac省选模拟赛]第11场题解集合
题目 比赛界面. T1 比较简单.容易想到是求鱼竿的最大独立集.由于题目的鱼竿可以被分割为二分图,就可以想到最大匹配. 尝试建边之后会发现边的数量不小,但联系题目性质会发现对于一条鱼竿,它 ...
- [noi.ac省选模拟赛20200606]赌怪
题目 点这里看题目. 分析 先特判掉\(K=2\)的情况. 首先可以考虑到一个简单 DP : \(f(i)\):前\(i\)张牌的最大贡献. 转移可以\(O(n^2)\)地枚举区间 ...
随机推荐
- Centos7 下安装以及使用mssql
Centos7下安装以及使用Mssql,在这下面玩,主要是发现linux环境下的mysql非常的小,小到只有169M,这在windows上面,动撤几个G的安装文件,会让你直接打消使用MSSQL的勇气, ...
- leetcode笔记9 Move Zeroes
题目要求: Given an array nums, write a function to move all 0's to the end of it while maintaining the r ...
- hive自定义函数——hive streaming
Hadoop Streaming提供了一个便于进行MapReduce编程的工具包,使用它可以基于一些可执行命令.脚本语言或其他编程语言来实现Mapper和 Reducer,Streaming方式是基于 ...
- AFD运维
1.afd 网址:https://www.dwd.de/AFD/html-en/contents.html 2.问题:拷贝了一个主机A配置后(HOST_CONFIG主机项),修改为另一个主机B配置:然 ...
- 使用postman实现半自动化
前些日子项目要上一个活动,其中有一个功能是幸运大转盘,用户可以随机抽奖,奖品有多种满减券及多种商品,但是奖品都是有抽中概率的,且有的商品还设置有库存,所以测试点便是测试抽奖的概率和库存.接下来拆分一下 ...
- lesson 23 one man's meat is another man's poison
lesson 23 one man's meat is another man's poison delicacy n. 美味:佳肴: delicious adj. 美味的:可口的 关于虚拟语气: I ...
- 【checkbox-group、checkbox】 多项选择器组件说明
checkbox-group组件包裹checkbox组件的容器 原型: <check-group bindchange="[EventHandle]"> <che ...
- leetcode-零钱兑换—int溢出
零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: c ...
- Python3 小工具-ARP扫描
from scapy.all import * import optparse import threading import os def scan(ipt): pkt=Ether(dst='ff: ...
- 一些容易记混的c++相关知识点
一些容易记混的c++相关知识. 截图自:<王道程序员面试宝典>