传送门

半平面交的讲解

然而这个代码真的是非常的迷……并不怎么看得懂……

//minamoto
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
using namespace std;
const int N=1e5+5;const double eps=1e-9;
inline int dcmp(const double &a){return fabs(a)>=eps?a<0?-1:1:0;}
struct node{double x,y;}pt[N];int tot;
inline node operator -(node a,node b){return {a.x-b.x,a.y-b.y};}
inline double operator *(node a,node b){return a.x*b.y-a.y*b.x;}
struct line{node a,b;}p[N],dq[N];int tp,bt,n;
inline bool aboveX(line a){
if(!dcmp(a.b.y-a.a.y))return dcmp(a.b.x-a.a.x)>0;
return dcmp(a.b.y-a.a.y)>0;
}
inline bool cmp(line a,line b){
if(aboveX(a)!=aboveX(b))return aboveX(a);
if(!dcmp((a.b-a.a)*(b.b-b.a)))return dcmp((a.b-a.a)*(b.b-a.a))<0;
return dcmp((a.b-a.a)*(b.b-b.a))>0;
}
inline node get(line a,line b){
double a1=a.b.y-a.a.y,b1=a.a.x-a.b.x,c1=a.a*a.b;
double a2=b.b.y-b.a.y,b2=b.a.x-b.b.x,c2=b.a*b.b;
double d=a1*b2-a2*b1;
return {(b2*c1-b1*c2)/d,(a1*c2-a2*c1)/d};
}
inline bool pd(line a,line b,line c){
node p=get(a,b);
return dcmp((p-c.a)*(c.b-c.a))>-1;
}
void solve(){
tot=1;
fp(i,1,n)if(dcmp((p[i].b-p[i].a)*(p[tot].b-p[tot].a)))p[++tot]=p[i];
n=tot,dq[bt=1]=p[1],dq[tp=2]=p[2];
fp(i,3,n){
while(tp>bt&&pd(dq[tp],dq[tp-1],p[i]))--tp;
while(tp>bt&&pd(dq[bt],dq[bt+1],p[i]))++bt;
dq[++tp]=p[i];
}
while(tp>bt&&pd(dq[tp],dq[tp-1],dq[bt]))--tp;
while(tp>bt&&pd(dq[bt],dq[bt+1],dq[tp]))++bt;
dq[++tp]=dq[bt],tot=0;
fp(i,bt,tp-1)pt[++tot]=get(dq[i],dq[i+1]);
}
double area(double s=0){
if(tot<3)return 0;pt[++tot]=pt[1];
fp(i,1,tot-1)s+=pt[i]*pt[i+1];
return 0.5*fabs(s);
}
int main(){
// freopen("testdata.in","r",stdin);
int T;scanf("%d",&T);
while(T--){
int ps;scanf("%d",&ps);
fp(i,1,ps)scanf("%lf%lf",&pt[i].x,&pt[i].y);
pt[0]=pt[ps];
fp(i,0,ps-1)p[++n].a=pt[i],p[n].b=pt[i+1];
}
sort(p+1,p+1+n,cmp);
solve();double ans=area();printf("%.3lf\n",ans);return 0;
}

P4196 [CQOI2006]凸多边形的更多相关文章

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

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

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

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

  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. 【BZOJ2618】[CQOI2006]凸多边形(半平面交)

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

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

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

  8. bzoj2618: [Cqoi2006]凸多边形

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

  9. BZOJ2618[Cqoi2006]凸多边形——半平面交

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

随机推荐

  1. Webdriver概述(selenium对应浏览器版本)

    Webdriver (Selenium2)是一种用于Web应用程序的自动测试工具,它提供了一套友好的API,与Selenium 1(Selenium-RC)相比,Webdriver 的API更容易理解 ...

  2. 客户端用plsql进行中文条件查询时无结果的解决办法

    1.SELECT * FROM v$nls_parameters ; 查看NLS_CHARACTERSET 的值是多少,我的AL32UTF8- 查找客户机器的注册表,查找NLS_LANG的值,改成AL ...

  3. hihoCoder#1036 Trie图

    原题地址 看了这篇博文,总算是把Trie图弄明白了 Runtime Error了无数次,一直不知道为什么,于是写了个脚本生成了一组大数据,发现果然段错误了. 调试了一下午,总算闹明白了,为什么呢? 1 ...

  4. hdu 1179最大匹配

    #include<stdio.h> #include<string.h> #define N 200 int map[N][N],visit[N],link[N],n,m; i ...

  5. HTML5调用传感器的资料汇总

    都可以调用:devicetemperature(温度).devicepressure(压力).devicehumidity(湿度).devicelight(光).devicenoise(声音).dev ...

  6. Rikka with Phi 线段树

    Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...

  7. Ubuntu 16.04 LTS GNOME版本下载

    下载地址: http://cdimage.ubuntu.com/ubuntu-gnome/releases/ Ubuntu GNOME发行版本启动已经有三年的时间了,在社区用户对于在稳定可靠的Ubun ...

  8. MYSQL 时间数据类型

  9. jmeter的master-slave模式

    要求: 1.相同的jmeter版本 2.最好相同的java版本 jmeter可以通过master-slave的方式实现更大的并发,但是作为master的机器将会消耗更多的资源,因为所有的slave的压 ...

  10. 多线程TcpServer

    多线程TcpServer自己的EventLoop只用来接收新连接(即TcpServer所属线程的EventLoop只监听listen fd),而新连接会用其他EventLoop来执行IO(即每个新Tc ...