题目描述

逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:

则相交部分的面积为5.233。

输入

第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。

输出

输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

样例输入

2
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0

样例输出

5.233

提示

100%的数据满足:2<=n<=10,3<=mi<=50,每维坐标为[-1000,1000]内的整数

半平面交模板题,就是求多边形所有边的半平面交。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-5;
struct lty
{
double x,y;
lty(double X=0,double Y=0){x=X,y=Y;}
};
struct miku
{
double x,y;
miku(double X=0,double Y=0){x=X,y=Y;}
};
struct line
{
lty s,t;
line(){}
line(lty S,lty T){s=S,t=T;}
};
miku operator -(lty a,lty b)
{
return miku(a.x-b.x,a.y-b.y);
}
miku operator *(miku a,double b)
{
return miku(a.x*b,a.y*b);
}
lty operator +(lty a,miku b)
{
return lty(a.x+b.x,a.y+b.y);
}
double get(miku a,miku b)
{
return a.x*b.y-a.y*b.x;
}
double tan(miku a)
{
return atan2(a.y,a.x);
}
double tan(line a)
{
miku res=a.t-a.s;
return atan2(res.y,res.x);
}
int n,m,k;
int cnt;
line a[100010];
line q[100010];
lty p[100010];
int D(double x)
{
if(fabs(x)<eps)
{
return 0;
}
return x<0?-1:1;
}
double ask(int num)
{
double ans=0;
for(int i=2;i<num;i++)
{
ans+=fabs(get(p[i]-p[1],p[i+1]-p[1]));
}
return ans/2.0;
}
bool cmp(line a,line b)
{
miku v1=a.t-a.s,v2=b.t-b.s;
double s1=tan(v1),s2=tan(v2);
int d=D(s1-s2);
if(!d)
{
return get(v1,b.t-a.s)>0;
}
return d<0;
}
lty find(line a,line b)
{
miku u=a.s-b.s,v=a.t-a.s,w=b.t-b.s;
if(!D(get(v,w)))
{
return a.s;
}
double x=get(w,u)/get(v,w);
return a.s+v*x;
}
bool check(line a,line b,line c)
{
lty e=find(b,c);
int d=D(get(a.t-a.s,e-a.s));
return d>0?false:true;
}
void solve()
{
sort(a+1,a+n+1,cmp);
int l=1,r=0;
int cnt=0;
for(int i=1;i<n;i++)
{
if(!D(tan(a[i])-tan(a[i+1])))
{
continue;
}
a[++cnt]=a[i];
}
a[++cnt]=a[n];
for(int i=1;i<=cnt;i++)
{
while(l<r&&check(a[i],q[r],q[r-1]))
{
r--;
}
while(l<r&&check(a[i],q[l],q[l+1]))
{
l++;
}
q[++r]=a[i];
}
while(l<r&&check(q[l],q[r],q[r-1]))
{
r--;
}
while(l<r&&check(q[r],q[l],q[l+1]))
{
l++;
}
int num=0;
for(int i=l;i<r;i++)
{
p[++num]=find(q[i],q[i+1]);
}
p[++num]=find(q[r],q[l]);
if(num<3)
{
printf("0.000");
return ;
}
printf("%.3f",ask(num));
}
int main()
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
cnt++;
if(i!=1)
{
a[cnt].s=a[cnt-1].t;
}
scanf("%lf%lf",&a[cnt].t.x,&a[cnt].t.y);
}
a[cnt-m+1].s=a[cnt].t;
}
n=cnt;
solve();
}

BZOJ2618[Cqoi2006]凸多边形——半平面交的更多相关文章

  1. bzoj2618[Cqoi2006]凸多边形 半平面交

    这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方 ...

  2. 【bzoj2618】[Cqoi2006]凸多边形 半平面交

    题目描述 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. 输入 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第 ...

  3. P4196 [CQOI2006]凸多边形 半平面交

    \(\color{#0066ff}{题目描述}\) 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. \(\color{#0066f ...

  4. luogu4196 [CQOI2006]凸多边形 半平面交

    据说pkusc出了好几年半平面交了,我也来水一发 ref #include <algorithm> #include <iostream> #include <cstdi ...

  5. POJ3525 半平面交

    题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...

  6. bzoj 4445 小凸想跑步 - 半平面交

    题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...

  7. 【kuangbin专题】计算几何_半平面交

    1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...

  8. bzoj 3190 赛车 半平面交

    直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...

  9. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

    传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...

随机推荐

  1. 【原创】Mysql中select的正确姿势

    引言 大家在开发中,还有很多童鞋在写查询语句的时候,习惯写下面这种不规范sql select * from table 而不写成下面的这种规范方式 select col1,col2,...,coln ...

  2. 苹果 icloud 把我 ipad min 所有照片丢失

    苹果 icloud 把我 ipad min 所有照片丢失,大概发生在 '云上贵州' 之后! 发帖纪念--- 求个说法---

  3. centos中docker的安装

    之前学习docker的时候,是在windows上直接使用可执行文件安装的,最近需要在自己的服务器上安装docker,特此了解了一下如何安装,这里补一下. 小白学Docker之基础篇 小白学Docker ...

  4. Python-SMTP发送邮件(HTML、图片、附件)

    前言: SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. 一.Python发送HTML ...

  5. Redux 入门教程(二):中间件与异步操作

    上一篇文章,介绍了 Redux 的基本做法:用户发出 Action,Reducer 函数算出新的 State,View 重新渲染. 但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后, ...

  6. 搜狐畅游一面(c++)

    上来是个小姐姐,有点懵.. 1.  介绍 2.  项目 3.  实习 4.  用的协议 tcp和udp的协议 5.  select 和epoll(忘了) 6. 数据库的隔离级别, 死锁, 怎么避免死锁 ...

  7. H5 video标签的属性

    35-video标签 video标签的属性 src: 用于告诉video标签需要播放的视频地址 autoplay: 用于告诉video标签是否需要自动播放视频 controls: 用于告诉video标 ...

  8. iOS-带图片的二维码的生成(QRCode)

    https://blog.csdn.net/feng512275/article/details/82824650 2018年09月23日 20:29:45 筝风放风筝 阅读数:91   版权声明:本 ...

  9. semantic-ui 容器与栅格

    semantic中可以指定one-sixteen这16个单词来指定网格column所占的长度.也就是说,在网页中,一行最多只有16个column,超过16个之后,自动移到下一行. 栅格可以使用i,di ...

  10. oracle事务的四个特性(ACID)

    事务产生的背景 当在PL/SQL中同时操作多个SQL语句,比如通过DML语句添加.修改或删除数据时,如何确保数据库数据不会因为意外而倒置错误数据是一个非常重要的问题. 以仓库发料系统为例,如果某一张领 ...