题目描述

逆时针给出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. A2D JS框架 - loadScript实现

    其实这个功能比较小,本着自己造轮子的优良传统....就自己造一个好了 <head> <title></title> <script src="A2D ...

  2. WebApi集成Swagger

    1.新建一个WebApi空项目 2.新建一个Person实体类: public class Person { public int ID { get; set; } public string Use ...

  3. 了解可执行的NPM包

    NPM是Node.js的包管理工具,随着Node.js的出现,以及前端开发开始使用gulp.webpack.rollup以及其他各种优秀的编译打包工具(大多数采用Node.js来实现),大家都开始接触 ...

  4. Python-os模块-60

    os 模块: 和操作系统打交道的模块 os模块是与操作系统交互的一个接口 os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirna ...

  5. H5 65-清除浮动方式一

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 安装pandas时出现环境错误

    在安装pandas时出现Could not install packages due to an EnvironmentErrorConsider using the `--user` option ...

  7. 打开指定测试App的指定Activity

    那究竟应该如何让appium去自动找到指定的APP和指定的Activity呢?想要打开指定的App,需要知道App的包名,同样想要打开指定Activity也需要知道其名,如何获取? 1.问公司的开发人 ...

  8. Debian搭建WordPress

    环境配置 可以使用apt-get快速安装mysql,php5:我是用源码手动安装apache服务器的.安装完mysql后,最好将字符编码设置为utf8的. 接下来就是mysql,apache,php5 ...

  9. Linux 典型应用之WebServer 安装和配置

    Apache的基本操作 安装 yum install httpd 启动 service httpd start  在浏览器中输入以下Ip 发现无法访问 http://192.168.1.109/ 输入 ...

  10. CSS响应式布局实例

    <style type="text/css">        body{            margin:0 auto;            min-width: ...