2618: [Cqoi2006]凸多边形

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 959  Solved: 489
[Submit][Status][Discuss]

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]内的整数

Source

Solution

裸半平面交

这里用的O(n^{2})的增量法,求完半平面交后再求多边形面积就好了,三角剖分一下就可以

一个不错的讲解

具体的做法:

•初始化时加上一个范围巨大的“框”
•每次拿一个新的半平面切割原先的凸集
•保留在新加直线左边的点,删除右边的,有向直线与多边形相交产生的新的点加入到新多边形内

Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<cstdlib>
using namespace std;
struct Vector
{
double x,y;
Vector(double X=,double Y=) {x=X,y=Y;}
};
typedef Vector Point;
typedef vector<Point> Polygon;
Polygon polygon;
#define MAXN 20
#define MAXM 100
Point P[MAXN][MAXM];
#define eps 1e-8
#define INF 1000
const double pi= acos(-1.0);
Vector operator + (Vector A,Vector B) {return ((Vector){A.x+B.x,A.y+B.y});}
Vector operator - (Vector A,Vector B) {return ((Vector){A.x-B.x,A.y-B.y});}
Vector operator * (Vector A,double p) {return ((Vector){A.x*p,A.y*p});}
Vector operator / (Vector A,double p) {return ((Vector){A.x/p,A.y/p});}
int dcmp(double x) {if(fabs(x)<eps) return ; else return x<? -:;}
bool operator == (const Vector& a,const Vector& b) {return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;}
double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}
double Len(Vector A) {return sqrt(Dot(A,A));}
double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;}
Point GLI(Point P,Vector v,Point Q,Vector w) {Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t;}
double DisTL(Point P,Point A,Point B) {Vector v1=B-A,v2=P-A; return fabs(Cross(v1,v2)/Len(v1));}
bool OnSegment(Point P,Point A,Point B) {return dcmp(DisTL(P,A,B))==&&dcmp(Dot(P-A,P-B))<&&!(P==A)&&!(P==B);}
double PolygonArea(Polygon p)
{
double area=;
int n=p.size();
for(int i=;i<n-;i++)
area+=Cross(p[i]-p[],p[i+]-p[]);
return area/;
}
Polygon CutPolygon(Polygon poly,Point A,Point B)
{
Polygon newpoly;
Point C,D,ip;
int n=poly.size(),i;
for(i=;i<n;i++)
{
C=poly[i];
D=poly[(i+)%n];
if(dcmp(Cross(B-A,C-A))>=)
newpoly.push_back(C);
if(dcmp(Cross(B-A,D-C))!=)
{
ip=GLI(A,B-A,C,D-C);
if(OnSegment(ip,C,D))
newpoly.push_back(ip);
}
}
return newpoly;
}
void InitPolygon(Polygon &poly,double inf)
{
poly.clear();
poly.push_back((Point){-inf,-inf});
poly.push_back((Point){inf,-inf});
poly.push_back((Point){inf,inf});
poly.push_back((Point){-inf,inf});
}
void Debug()
{
for (int j=; j<polygon.size(); j++)
printf("(%.1lf,%.1lf)-->",polygon[j].x,polygon[j].y);
printf("(%.1lf,%.1lf)",polygon[].x,polygon[].y);
puts("");
}
int main()
{
int N,M;
scanf("%d",&N);
InitPolygon(polygon,INF);
for (int i=; i<=N; i++)
{
scanf("%d",&M);
for (int j=; j<=M; j++)
scanf("%lf%lf",&P[i][j].x,&P[i][j].y);
P[i][M+]=P[i][];
for (int j=; j<=M; j++)
{polygon=CutPolygon(polygon,P[i][j],P[i][j+]); /*Debug();*/}
}
printf("%.3lf\n",PolygonArea(polygon));
return ;
}

自己调个模板,p事怎么这么多QAQ

【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. bzoj 3190 [JLOI2013]赛车 半平面交+细节处理

    题目大意 这里有一场赛车比赛正在进行,赛场上一共有N辆车,分别称为g1,g2--gn.赛道是一条无限长的直线.最初,gi位于距离起跑线前进ki的位置.比赛开始后,车辆gi将会以vi单位每秒的恒定速度行 ...

  8. bzoj 1038 瞭望塔 半平面交+分段函数

    题目大意 给你一座山,山的形状在二维平面上为折线 给出\((x_1,y_1),(x_2,y_2)...(x_n,y_n)\)表示山的边界点或转折点 现在要在\([x_1,x_n]\)(闭区间)中选择一 ...

  9. POJ 3384 Feng Shui(计算几何の半平面交+最远点对)

    Description Feng shui is the ancient Chinese practice of placement and arrangement of space to achie ...

随机推荐

  1. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  2. usb驱动开发18之设备生命线

    现在已经使用GET_DESCRIPTOR请求取到了包含一个配置里所有相关描述符内容的一堆数据,这些数据是raw的,即原始的,所有数据不管是配置描述符.接口描述符还是端点描述符都挤在一起,所以得想办法将 ...

  3. 【转】【MySql】Waiting for table metadata lock原因分析

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  4. Xcode里-ObjC, -all_load, -force_load

    最近在做一个项目的时候,需要使用到一个第三方库,这个库的使用向导里面特别说明,在添加完该库后,需要在Xcode的Build Settings下Other Linker Flags里面加入-ObjC标志 ...

  5. c++多重继承小结

    如果一个类从两个不同的类里继承两个同名的成员,则需要在派生类中使用类限定符来区分他们. 即在从A和B派生出来的c类中使用a::Show()和B::Show()来区分从这两个类那里继承的show()方法 ...

  6. .NET C#微信公众号开发远程断点调试(本地远程调试生产环境代码)

    最近在做微信公众号开发,由于之前没有接触过,突然发现调试不方便,不方便进行断点跟踪调试.因为微信那边绑定的服务器地址必须是公网地址,但是还是想进行断点调试(毕竟这样太方便了,程序有Bug,一步步断点跟 ...

  7. HoloLens开发手记 - Vuforia开发概述 Vuforia development overview

    关于Vuforia,开发AR应用的人基本都会熟悉.之前我也写过一篇关于Vuforia开发的博客:Vuforia AR SDK入门 今天这篇博客则主要是谈谈HoloLens使用Vuforia开发混合现实 ...

  8. nios II--实验2——led硬件部分

    Led 硬件开发 新建原理图 1.打开Quartus II 11.0,新建一个工程,File -> New Project Wizard…,忽略Introduction,之间单击 Next> ...

  9. Nginx的配置文件

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  10. 东大oj-1591 Circle of friends

    题目描述 Nowadays, "Circle of Friends" is a very popular social networking platform in WeChat. ...