描述

给一些多边形求重叠面积

分析

半平面交的模版

注意别少加了直线

#include #include #include #include using namespace std;
struct Point {
double x, y;
Point(double x=0, double y=0):x(x),y(y) { }
};
typedef Point Vector;
Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); }
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; }
double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; }
double Length(const Vector& A) { return sqrt(Dot(A, A)); }
Vector Normal(const Vector& A) {
double L = Length(A);
return Vector(-A.y/L, A.x/L);
}
double PolygonArea(vectorp) { int n = p.size(); double area = 0; for(int i = 1; i < n-1; i++) area += Cross(p[i]-p[0], p[i+1]-p[0]); return area/2; } // 有向直线。它的左边就是对应的半平面 struct Line { Point P; // 直线上任意一点 Vector v; // 方向向量 double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度) Line() {} Line(Point P, Vector v):P(P),v(v) { ang = atan2(v.y, v.x); } bool operator < (const Line& L) const { return ang < L.ang; } }; // 点p在有向直线L的左边(线上不算) bool OnLeft(const Line& L, const Point& p) { return Cross(L.v, p-L.P) > 0; } // 二直线交点,假定交点惟一存在 Point GetLineIntersection(const Line& a, const Line& b) { Vector u = a.P-b.P; double t = Cross(b.v, u) / Cross(a.v, b.v); return a.P+a.v*t; } const double INF = 1e8; const double eps = 1e-6; // 半平面交主过程 vectorHalfplaneIntersection(vectorL) { int n = L.size(); sort(L.begin(), L.end()); // 按极角排序 int first, last; // 双端队列的第一个元素和最后一个元素的下标 vectorp(n); // p[i]为q[i]和q[i+1]的交点 vectorq(n); // 双端队列 vectorans; // 结果 q[first=last=0] = L[0]; // 双端队列初始化为只有一个半平面L[0] for(int i = 1; i < n; i++) { while(first < last && !OnLeft(L[i], p[last-1])) last--; while(first < last && !OnLeft(L[i], p[first])) first++; q[++last] = L[i]; if(fabs(Cross(q[last].v, q[last-1].v)) < eps) { // 两向量平行且同向,取内侧的一个 last--; if(OnLeft(q[last], L[i].P)) q[last] = L[i]; } if(first < last) p[last-1] = GetLineIntersection(q[last-1], q[last]); } while(first < last && !OnLeft(q[first], p[last-1])) last--; // 删除无用平面 if(last - first <= 1) return ans; // 空集 p[last] = GetLineIntersection(q[last], q[first]); // 计算首尾两个半平面的交点 // 从deque复制到输出中 for(int i = first; i <= last; i++) ans.push_back(p[i]); return ans; } int main() { int n, m; scanf("%d", &n); vectorL; for(int i = 0; i < n; i++) { vectorp; scanf("%d", &m); for(int j = 0; j < m; j++) { double x, y; scanf("%lf %lf", &x, &y); p.push_back(Point(x, y)); if(j) L.push_back(Line(p[j], p[j]-p[j-1])); } L.push_back(Line(p[m-1], p[0]-p[m-1])); } vectorp = HalfplaneIntersection(L); double ans = PolygonArea(p); printf("%.3lf", ans); return 0; } 

BZOJ-2618-凸多边形-CQOI2006相关推荐

  1. BZOJ刷题记录---提高组难度

    BZOJ刷题记录---提高组难度 总目录详见https://blog.csdn.net/mrcrack/article/details/90228694 序号 题号 算法 思想难度 实现难度 总难度 ...

  2. [学习笔记]半平面交

    一个直线把平面分成两部分,就是两个半平面 处理这两个平面的交的信息,就是半平面交 推荐: 计算几何之半平面交算法模板及应用 bzoj 2618 半平面交模板+学习笔记 [总结]半平面交 可以用于求任意 ...

  3. 一句话题解(20180210~)

    2.9 BZOJ 2006 [NOI2010]超级钢琴.这道题目几天之前就做了.做法是固定右端点,左端点在ST表上走,走法其实就是笛卡尔树的走法.完结撒花! BZOJ 1218 [HNOI2003]激 ...

  4. 2618: [Cqoi2006]凸多边形

    半平面交裸题,即便如此本辣鸡还是调试了一上午- 因为是求所有图形的交,那么直接把每个图形都拆成一堆直线, 相当于每次切一刀,留下左边的,然后求最后面积 c++代码如下: #include<bit ...

  5. bzoj2618 [Cqoi2006]凸多边形

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

  6. P4196 [CQOI2006]凸多边形 /【模板】半平面交

    P4196 [CQOI2006]凸多边形 /[模板]半平面交 本来是个板子题,而且我这个板子之前在POJ写过一些题目了,但是这里一直让我RE. 后来解决办法竟然是:先读入第一个多边形不加边(存下来), ...

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

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

  8. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  9. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

  10. java n个点 凸多边形_hrbustoj 1291 点在凸多边形内

    分析:因为是凸多边形,所以只要对每条边求一下叉积即可. 设有向量P和Q则它们的叉积PXQ有以下性质: 1.PXQ>0  时,则P在Q的顺时针方向: 2.PXQ<0  时,则P在Q的逆时针方 ...

最新文章

  1. apache加入chkconfig
  2. word 通配符_word通配符技巧:HR高效办公技巧应用
  3. 关于kali相关的参考文章
  4. OJ系列之---字符串分割
  5. 数据中台推荐系统入门(二):两种经典的推荐算法
  6. 递归算法——汉诺塔问题
  7. WINDOWS 2008 AD权限管理服务(ADRMS)完全攻略
  8. Java面向对象(15)--static关键字静态理解与使用
  9. 用计算机唱出惊雷,除了《惊雷》还有多少喊麦神曲?这十首神作你一定听过!...
  10. java工程师占比_Java工资怎么样?哪个地方Java工作机会最多?
  11. python-socket客户服务端的传输原理异常关闭的情况
  12. Stream介绍及简单操作!
  13. word模板文档替换,解决并发导致替换失败
  14. SocksCap64应用程序通过SOCKS代理
  15. Java 度分秒转经纬度,经纬度转度分秒,度分转经纬度,经纬度转度分
  16. html状态码206,http状态码204/206/200理解
  17. iPad作为Windows电脑副屏使用技巧(详细向)
  18. 与技术无关,但却值得码农们好好读一读的怪书:禅与摩托车维修艺术
  19. 基于Spring Security 的Java SaaS应用的权限管理
  20. win10两个磁盘合并成一个?win10系统怎么合并磁盘

热门文章

  1. A humble heart2019-11-09
  2. 撒花!PyTorch 官方教程中文版正式上线,激动人心的大好事!
  3. python嵌套字典代码_python – 尝试在嵌套字典中查找唯一值的总和. (见例子!)
  4. C++ BUILDER 消息处理的深入探索
  5. 在ASP.NET中怎么用SESSION判断用户是否登录
  6. linux-IO之copy的实现
  7. sort函数——利用函数实现快速排序c++
  8. git status 命令总结 —— Git 学习笔记 06
  9. MySQL到Elasticsearch数据同步
  10. UNIX再学习 -- 函数abort