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=0,double Y=0) {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 0; else return x<0? -1:1;}
bool operator == (const Vector& a,const Vector& b) {return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}
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))==0&&dcmp(Dot(P-A,P-B))<0&&!(P==A)&&!(P==B);}
double PolygonArea(Polygon p)
{double area=0;int n=p.size();for(int i=1;i<n-1;i++)area+=Cross(p[i]-p[0],p[i+1]-p[0]);return area/2;
}
Polygon CutPolygon(Polygon poly,Point A,Point B)
{Polygon newpoly;Point C,D,ip;int n=poly.size(),i;for(i=0;i<n;i++){C=poly[i];D=poly[(i+1)%n];if(dcmp(Cross(B-A,C-A))>=0)newpoly.push_back(C);if(dcmp(Cross(B-A,D-C))!=0){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=0; j<polygon.size(); j++)printf("(%.1lf,%.1lf)-->",polygon[j].x,polygon[j].y);printf("(%.1lf,%.1lf)",polygon[0].x,polygon[0].y);puts("");
}
int main()
{int N,M;scanf("%d",&N);InitPolygon(polygon,INF);for (int i=1; i<=N; i++){            scanf("%d",&M);for (int j=1; j<=M; j++)scanf("%lf%lf",&P[i][j].x,&P[i][j].y);P[i][M+1]=P[i][1];for (int j=1; j<=M; j++){polygon=CutPolygon(polygon,P[i][j],P[i][j+1]); /*Debug();*/}}printf("%.3lf\n",PolygonArea(polygon));return 0;
}

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

转载于:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5682592.html

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

  1. P4196-[CQOI2006]凸多边形/[模板]半平面交【计算几何】

    正题 题目链接:https://www.luogu.com.cn/problem/P4196 题目大意 给出nnn个凸多边形,求它们交的面积. 解题思路 就是把凸多边形上每条边作为一个半平面限制然后求 ...

  2. [模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

    一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson Simpson's Rule: \[ \int ^b_a f(x)dx\approx ...

  3. [凸多边形最大内切圆][半平面交]Most Distant Point from the Sea POJ3525

    The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it is na ...

  4. UVA1396 Most Distant Point from the Sea(AM - ICPC - Tokyo - 2007)(计算几何,半平面交 + 二分答案)

    整理的算法模板合集: ACM模板 题目传送门 见<训练指南>P279 很明显就是一个二分答案,它问的是最远的点,直接枚举因为这里都是double类型的数所以有无限个点,我们可以直接二分. ...

  5. 模板:半平面交(计算几何)

    所谓半平面交,就是和"半平先生"当面交谈.顾名思义,这是一个源于日本的算法. (逃) 前言 感觉应用很灵活的一个算法,一切有两个变量的线性规划问题都可以转化为半平面交. 有时可能要 ...

  6. [BZOJ 1038][ZJOI 2008]瞭望塔(半平面交)

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1038 思路 这个题在上海ACM/ICPC冬令营的比赛中也考过,不是很难,不过想要想到用半平 ...

  7. 半平面交练习(计算几何)

    四:半平面交 Rotating Scoreboard /*Author : lifehappy */ #include <cstdio> #include <cmath> #i ...

  8. BZOJ 3564: [SHOI2014]信号增幅仪(随机增量法)

    如果是个圆的话好办,如果是拉成椭圆呢?直接压回去!!! 然后随机增量法就行了 CODE: #include<cstdio> #include<iostream> #includ ...

  9. 随机增量法:bzoj 1336 bzoj 1337 最小圆覆盖

    1337: 最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 1170  Solved: 573 [Submit][Status][Discus ...

最新文章

  1. Python对象类型——字符串、列表、元组
  2. css学习笔记2--多重边框
  3. Java Review - 使用Event Bus实现目录变化的监控
  4. ASP.NET MVC 5 学习教程:Details 和 Delete 方法详解
  5. halcon/c++接口基础 之 析构函数和Halcon算子
  6. java jri_Java调用R(二)_JRI | 学步园
  7. 总结MyBatis+Spring的整合
  8. [UOJ455][UER #8]雪灾与外卖——堆+模拟费用流
  9. 太平洋女性网焦点图的几种写法
  10. java clob 操作_java操作clob字段
  11. anime.js 图片位移动画_打造高大上的Canvas粒子动画
  12. python模块介绍二。
  13. Tcl 语言——Synopsys Tcl篇
  14. Watir的操作使用
  15. java web web.xml配置_web.xml配置详解
  16. 怎样快速学习一门新技术
  17. 机器学习项目实践——K-means聚类实现广告分析
  18. 从零开发区块链应用(十一)--以太坊地址生成
  19. 降龙十八掌搞定rt3070 USB WIFI模块在android2.3平台上上网[基于x210开发板]
  20. MIT 18.06 +线性代数的几何意义+3Blue1Brown 笔记

热门文章

  1. 数据科学家教你用数据模型来泡妞
  2. 双变量空间自相关_空间计量经济学的发展及其应用,经济模型总会需要
  3. 本博客体系系列篇(一)
  4. clickhouse算术函数
  5. 三、JVM — 类加载过程
  6. 聊聊Elasticsearch的BootstrapCheck
  7. 在使用Git提交代码的时候犯了个低级错误
  8. Windows 10中Cisco *** Client提示Reason 442: failed to enable virtual adapter
  9. Android中文API(98)—— ContextMenu.ContextMenuInfo
  10. [转载]直接保存Matlab图像到PPT文件