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. 你以为大厂的代码就不烂?看看这几个公众号怎么说!
  2. [转]淘宝下单高并发解决方案
  3. 和搜狗输入法快捷键冲突_电脑输入法怎么设置成搜狗双拼?
  4. RocketMQ集群之搭建2m2s集群(配置说明)
  5. 实际应用中带头节点的线性链表
  6. 技术动态 | 知识图谱构建的研究已走入下半场,但大规模落地应用仍需时间
  7. 零基础学python用哪本书好-零基础想要学习Python编程 ,不知道看哪本书?
  8. c语言程序设计火车站售票系统,C语言程序-火车站售票系统程序
  9. Jenkins 部署(Docker)
  10. leetcode-买卖股票的最佳时机含手续费
  11. mybatis xml 格式化时间查询
  12. mysql韩语排序_MySQL汉字字段按拼音排序
  13. 树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键)
  14. JAVA表示姓名和对应的出生日期
  15. 美业选择会员系统的原因
  16. MATLAB 矩阵的合并方法
  17. 基于python的国内外研究现状怎么写_如何写国内外研究现状
  18. 用Google Analytics监控营销邮件打开率
  19. mybatisplus学习之通用的Service(四)
  20. 网络尖兵的另类破解。

热门文章

  1. jsp中提供的四种属性范围
  2. android模拟器 opengl,android模拟器用到android.opengl.glsurfaceview报错怎么办
  3. java 得到bean的属性_获取javaBean所有属性及类型.doc
  4. Stanford机器学习---第4讲. 神经网络的表示 Neural Networks representation
  5. python库怎么绘画_python中的turtle库(图形绘画库)
  6. 用计算机算3次根号0.00005,数值分析复习题13
  7. 5. 吴恩达机器学习课程-作业5-偏差和方差
  8. C语言:某班有N名同学,每个学生的信息包括学号、姓名、三门课的成绩,从键盘输入名学生的信息,打印出N名学生三门课的平均成绩,以及最高分学生的信息(包括学号,姓名,三门课的成绩,平均分)
  9. php相关术语,PHP中一些专业术语、符号、函数[初学者学习PHP]
  10. 依赖 netty spring_面试官:如何写好一个 Spring 组件?懵圈!