题目描述

逆时针给出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. Java过滤掉字符串中的html标签、style标签、script标签

    使用正则表达式 import java.util.regex.Matcher; import java.util.regex.Pattern; public class HTMLSpirit{ pub ...

  2. Android开发之自定义万能BaseAdapter

    话不多说哦,直接上模板: package com.zyzpp.adapter; import android.content.Context; import android.util.SparseAr ...

  3. Linux 用户身份与进程权限

    在学习 Linux 系统权限相关的主题时,我们首先关注的基本都是文件的 ugo 权限.ugo 权限信息是文件的属性,它指明了用户与文件之间的关系.但是真正操作文件的却是进程,也就是说用户所拥有的文件访 ...

  4. NanoFabric-ServiceFabric 操作手册

    service-fabric-52abp-ocelot A Service Fabric sample with a Frontend, one API Gateway and 52abp Micro ...

  5. H5 54-清空默认边距

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

  6. poj2594 机器人寻找宝藏(最小路径覆盖)

    题目来源:http://poj.org/problem?id=2594 参考博客:http://www.cnblogs.com/ka200812/archive/2011/07/31/2122641. ...

  7. Python学习第十二篇——切片的使用

    Python中使用函数切片可以创建副本,保留原本.现在给出如下代码 magicians_list = ['mole','jack','lucy'] new_lists = [] def make_gr ...

  8. Mike and distribution CodeForces - 798D (贪心+思维)

    题目链接 TAG: 这是我近期做过最棒的一道贪心思维题,不容易想到,想到就出乎意料. 题意:给定两个含有N个正整数的数组a和b,让你输出一个数字k ,要求k不大于n/2+1,并且输出k个整数,范围为1 ...

  9. web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法

    问题描述 最近将公司官网样式进行了调整,部署到服务器后访问发现页面展示不正常,但是刷新之后就会展示正常. 问题分析 研究之后发现可能的原因有 css文件过大,加载缓慢 本地缓存问题,虽然服务器修改了c ...

  10. C#复习笔记(3)--C#2:解决C#1的问题(实现迭代器的捷径)

    实现迭代器的捷径 从这个题目上可以看到C#1实现一个迭代器模式的话是多么的痛苦,我自己也写过不下40行的代码来实现一个迭代器,C#中的迭代器模式是通过IEnumerable和他的泛型等价物IEnume ...