讲解:

这里套用wuvin神犇的ppt,附上友情链接:http://blog.leanote.com/wuvin

半平面交:

算法流程:

注意事项:

例题:

Description

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

则相交部分的面积为5.233。

Input

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

Output

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

Sample Input

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

Sample Output

5.233

HINT

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

题解:

  半平面交裸题

心得:

  主要是代码很烦吧···一定要理清点与点之间的关系,多画图帮助理解;

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=;
struct point
{
double x;
double y;
}p[N],a[N];
struct line
{
point a;
point b;
double slope;
}l[N],q[N];
inline double operator * (point a,point b)
{
return a.x*b.y-a.y*b.x;
}
inline point operator - (point a,point b)
{
point t;
t.x=a.x-b.x;
t.y=a.y-b.y;
return t;
}
inline point inter(line a,line b)
{
double k1=(b.b-a.a)*(a.b-a.a);
double k2=(a.b-a.a)*(b.a-a.a);
double t=k1/(k1+k2);
point k;
k.x=b.b.x+(b.a.x-b.b.x)*t;
k.y=b.b.y+(b.a.y-b.b.y)*t;
return k;
}
bool jud(line a,line b,line c)
{
point t=inter(a,b);
return (t-c.a)*(c.b-c.a)>;
}
int n,k,cnt,tot;
double ans;
bool comp(line a,line b)
{
if(a.slope!=b.slope) return a.slope<b.slope;
else return (b.b-a.a)*(a.b-a.a)<;
}
void build()
{
sort(l+,l+cnt+,comp);
/*for(int i=1;i<=cnt;i++)
cout<<l[i].a.x<<' '<<l[i].a.y<<' '<<l[i].b.x<<' '<<l[i].b.y<<endl;*/
for(int i=;i<=cnt;i++)
{
if(l[i].slope!=l[i-].slope)tot++;
l[tot]=l[i];
}
int left=,right=;
q[++right]=l[];
q[++right]=l[];
cnt=tot,tot=;
for(int i=;i<=cnt;i++)
{
while(left<right&&jud(q[right-],q[right],l[i])) right--;
while(left<right&&jud(q[left+],q[left],l[i])) left++;
q[++right]=l[i];
}
while(left<right&&jud(q[right-],q[right],q[left])) right--;
while(left<right&&jud(q[left+],q[left],q[right])) left++;
q[right+]=q[left];
for(int i=left;i<=right;i++)
a[++tot]=inter(q[i],q[i+]); }
void getans()
{
if(tot<) return;
a[tot+]=a[];
for(int i=;i<=tot;i++)
ans+=a[i]*a[i+];
ans=fabs(ans)/;
}
int main()
{
//freopen("a.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&k);
for(int j=;j<=k;j++)
scanf("%lf%lf",&p[j].x,&p[j].y);
p[k+]=p[];
for(int j=;j<=k;j++)
{
l[++cnt].a=p[j];
l[cnt].b=p[j+];
}
}
/*for(int i=1;i<=cnt;i++)
cout<<l[i].a.x<<' '<<l[i].a.y<<' '<<l[i].b.x<<' '<<l[i].b.y<<endl;*/
for(int i=;i<=cnt;i++)
l[i].slope=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
build();
getans();
printf("%.3lf\n",ans);
return ;
}
 

算法复习——半平面交(bzoj2618凸多边形)的更多相关文章

  1. 【BZOJ2618】[CQOI2006]凸多边形(半平面交)

    [BZOJ2618][CQOI2006]凸多边形(半平面交) 题面 BZOJ 洛谷 题解 这个东西就是要求凸多边形的边所形成的半平面交. 那么就是一个半平面交模板题了. 这里写的是平方的做法. #in ...

  2. 【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 959  Solved: 489[Submit][Status] ...

  3. 【BZOJ 2618】 2618: [Cqoi2006]凸多边形 (半平面交)

    2618: [Cqoi2006]凸多边形 Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. Input 第一 ...

  4. bzoj 2618 2618: [Cqoi2006]凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 656  Solved: 340[Submit][Status] ...

  5. bzoj 2618: [Cqoi2006]凸多边形 [半平面交]

    2618: [Cqoi2006]凸多边形 半平面交 注意一开始多边形边界不要太大... #include <iostream> #include <cstdio> #inclu ...

  6. 2018.07.04 BZOJ 2618 Cqoi2006凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MB Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n ...

  7. BZOJ - 2618 凸多边形 (半平面交)

    题意:求n个凸多边形的交面积. 半平面交模板题. #include<bits/stdc++.h> using namespace std; typedef long long ll; ty ...

  8. 洛谷 P4196 [CQOI2006]凸多边形 (半平面交)

    题目链接:P4196 [CQOI2006]凸多边形 题意 给定 \(n\) 个凸多边形,求它们相交的面积. 思路 半平面交 半平面交的模板题. 代码 #include <bits/stdc++. ...

  9. [CQOI2006]凸多边形(半平面交)

    很明显是一道半平面交的题. 先说一下半平面交的步骤: 1.用点向法(点+向量)表示直线 2.极角排序,若极角相同,按相对位置排序. 3.去重,极角相同的保留更优的 4.枚举边维护双端队列 5.求答案 ...

随机推荐

  1. More helpful Cocos2d and Gaming macros

    More helpful Cocos2d and Gaming macros Here are w few macros that i wrote to make the code more read ...

  2. 联想e431笔记本更改硬盘模式bios设置的详细教程

    用硬盘安装系统,就要进入bios,将硬盘改为第一启动项即可重装系统.不同品牌的电脑,它的bios设置方法也就不同.那么,联想e431笔记本要如何更改硬盘模式呢?今天U大侠小编就和大家分享联想e431笔 ...

  3. UVA821 PageHopping (Floyd)

    求所有点直接的平均最短距离,保存一下出现过的点,题目保证是所有点连通,Floyd求出最短路以后两个for统计一下. #include<bits/stdc++.h> using namesp ...

  4. leetcode_1049. Last Stone Weight II_[DP]

    1049. Last Stone Weight II https://leetcode.com/problems/last-stone-weight-ii/ 题意:从一堆石头里任选两个石头s1,s2, ...

  5. webpack之postcss集成

    项目 为了 兼容各个浏览器,需要加各种 c3前缀,如果手动的加肯定 相对比较麻烦,但是现在有webpack,gulp之类的 工具可以自动给我们加上,可以说效率上加速不少.如果 配置中 做个happyp ...

  6. Bootstrap历练实例:分页的大小

    分页的大小 下面的实例演示了上表中所讨论的 class .pagination-* 的用法: <!DOCTYPE html><html><head><meta ...

  7. Bootstrap历练实例:表单控件状态(禁用)

    禁用的输入框 input 如果您想要禁用一个输入框 input,只需要简单地添加 disabled 属性,这不仅会禁用输入框,还会改变输入框的样式以及当鼠标的指针悬停在元素上时鼠标指针的样式. < ...

  8. javase(8)_集合框架_List、Set、Map

    一.集合体系(不包括Queue体系) 二.ArrayList ArrayList的属性 private transient Object[] elementData; //存储元素 private i ...

  9. RedHat7搭建KVM虚拟机

    RedHat7搭建KVM虚拟机 1. 宿主机安装RedHat7.3系统 1.1选择语言 中文.简体中文(中国) 1.2安装位置 1.2.1自定义分区,选择LVM,将分区空间全部分配给根 1.2.2禁用 ...

  10. C# Excel常用控件总结

    参考:https://blog.csdn.net/waterstar50/article/details/80590355 1.ClosedXML2.EPPlus 教程:http://www.cnbl ...