题目描述

逆时针给出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. Git&Github基本操作与分支管理

    Git的原理涉及快照流.链表.指针等,这里不作过多叙述. 1.基本操作 git init 创建一个 Git 仓库 git clone [url] 拷贝一个 Git 仓库到本地 git add [fil ...

  2. Python股票分析系列——自动获取标普500股票列表.p5

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第5部分.在本教程和接下来的几节中,我们将着手研究如何为更多公司提供大量的定价信息,以及如何一次 ...

  3. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 发送通知功能改进改进

    公司有几万个用户,接近10万人,有一些紧急的通知,消息提醒,可以发个及时通知工具,这样可以快速把一些信息通知给大家,让大家快速收到信息,及时通知到系统的每个人. 自动提示信息现实状态,会在客户端自动谈 ...

  4. Oracle记录表删除操作简单方法

    最近项目中Oracle库中一个表log_gpackage有数据丢失现象,但因为没有启用归档,所以CDC和Dataguard都无法使用.google一下,最简单的方法,增加触发器处理逻辑: ---创建触 ...

  5. CISCO交换机-SNMP配置

    1.1     SNMP基础配置 router> enable 进入路由器是用户模式 router# conf terminal 进入路由器的全局配置模式 #snmp-server commun ...

  6. 01 Django REST Framework 介绍

    01-Django REST Framework的介绍 Django REST框架是一个用于构建Web API的强大而灵活的工具包. 您可能希望使用REST框架的一些原因: 1. Web可浏览API对 ...

  7. Python全栈开发之路 【第八篇】:面向对象编程设计与开发(2)

    一.继承与派生 什么是继承? 继承指的是类与类之间的关系,是一种什么是什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创建新的类的方式,在python中,新建的类可以继承一个或多个父类 ...

  8. 小P的字符串

    题目描述 小P最近在研究字符编码,给出一串由0.1组成的字符串,从中任意进行截取,如果截取的字符串对应一个英文字母的ASCII值,小P就把这个0.1串叫字母子串,问给定的字符串最多能截取出多少个字母子 ...

  9. NOIP2016解题报告

    天天听这几道题,但其实题面都没看过.今天做一下. 每道题看懂题后基本一分钟左右就切了.D2T3想的是\(O(n\log n)\)的堆做法,至少90分吧. D1T1模拟即可. D1T2每条路径拆成到根的 ...

  10. c语言之字符输入输出和输入验证

    单字符I/O:getchar()和putchar() #include<stdio.h> int main(void) { char ch; while ((ch = getchar()) ...