[BZOJ 2618][CQOI 2006]凸多边形(半平面交+三角剖分求多边形面积)
来源:互联网 发布:速卖通数据分析工具 编辑:程序博客网 时间:2024/06/03 17:19
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=2618
思路
实际上就是很多条直线求半平面交的面积,这是很显然的。
所以直接用半平面交+三角剖分模板就能水过。
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <cmath>#define MAXN 10000#define EPS 1e-6using namespace std;int dcmp(double a){ if(fabs(a)<EPS) return 0; if(a>EPS) return 1; return -1;}struct Point{ double x,y; Point(){} Point(double _x,double _y):x(_x),y(_y){}}points[MAXN],polygon[MAXN];int n=0,sizeOfPoly=0;Point operator-(Point a,Point b){ return Point(a.x-b.x,a.y-b.y);}Point operator+(Point a,Point b){ return Point(a.x+b.x,a.y+b.y);}Point operator*(Point a,double b){ return Point(a.x*b,a.y*b);}Point operator/(Point a,double b){ return Point(a.x/b,a.y/b);}double operator*(Point a,Point b){ return a.x*b.x+a.y*b.y;}double cross(Point a,Point b){ return a.x*b.y-a.y*b.x;}struct Line{ Point st,ed; double ang; Line(){} Line(Point _st,Point _ed):st(_st),ed(_ed) { ang=atan2((st-ed).y,(st-ed).x); }}lines[MAXN],q[MAXN];int top=0,h=1,t=0;Point getLineIntersec(Line a,Line b){ double x=cross(a.ed-a.st,b.ed-b.st); //!!!!! double y=cross(b.st-a.st,a.ed-a.st); return b.st+(b.ed-b.st)*y/x;}bool cmp(Line a,Line b) //按照极角升序排序{ if(!dcmp(a.ang-b.ang)) return dcmp(cross(a.ed-a.st,b.ed-a.st))>0; return dcmp(a.ang-b.ang)<0;}bool onLeft(Line a,Point b){ return dcmp(cross(b-a.st,a.ed-a.st))<=0;}void HalfPanelIntersec() //半平面交{ int tot=0; sort(lines+1,lines+n+1,cmp); for(int i=1;i<=n;i++) //去掉极角相同的直线 { if(dcmp(lines[i].ang-lines[i-1].ang)) tot++; lines[tot]=lines[i]; } q[++t]=lines[1],q[++t]=lines[2]; for(int i=1;i<=tot;i++) { while(h<t&&!onLeft(lines[i],getLineIntersec(q[t-1],q[t]))) t--; if(h<t&&!dcmp(fabs(cross(q[t].ed-q[t].st,q[t-1].ed-q[t-1].st)))) { if(onLeft(q[t],lines[i].st)) //i与队尾直线平行且方向相同,则需要保留靠近半平面交内部的那条 q[t]=lines[i]; } else q[++t]=lines[i]; } while(t-h>=2&&!onLeft(q[t],getLineIntersec(q[h],q[h+1]))) h++; while(t-h>=2&&!onLeft(q[h],getLineIntersec(q[t],q[t-1]))) t--; for(int i=h;i<t;i++) polygon[++sizeOfPoly]=getLineIntersec(q[i],q[i+1]); polygon[++sizeOfPoly]=getLineIntersec(q[t],q[h]);}double getSqrOfPolygon(){ double sqr=0; if(sizeOfPoly<=2) return 0; polygon[++sizeOfPoly]=polygon[1]; for(int i=1;i<=sizeOfPoly;i++) sqr+=cross(polygon[i],polygon[i+1]); return fabs(sqr)/2;}int main(){ int m; scanf("%d",&m); for(int i=1;i<=m;i++) { int cnt=0; scanf("%d",&cnt); Point p1,p2,tmp; scanf("%lf%lf",&p1.x,&p1.y); tmp=p1; for(int j=2;j<=cnt;j++) { scanf("%lf%lf",&p2.x,&p2.y); lines[++n]=Line(p1,p2); p1=p2; } lines[++n]=Line(p1,tmp); } HalfPanelIntersec(); printf("%.3lf\n",getSqrOfPolygon()); return 0;}
0 0
- [BZOJ 2618][CQOI 2006]凸多边形(半平面交+三角剖分求多边形面积)
- BZOJ 2618 CQOI 2006 凸多边形 半平面交
- BZOJ 2618 CQOI 2006 凸多边形 半平面交
- BZOJ 2618 CQOI2006 凸多边形 半平面交
- 【BZOJ 2618】[Cqoi2006]凸多边形 半平面交
- BZOJ 2618 [Cqoi2006]凸多边形 半平面交
- 【bzoj 2618】凸多边形(半平面交)
- ecnu1624求交集多边形面积 (凸多边形交——半平面交)
- bzoj 2618: [Cqoi2006]凸多边形 (半平面交)
- bzoj 2618: [Cqoi2006]凸多边形(半平面交模板)
- BZOJ 2618: [Cqoi2006]凸多边形(半平面交)
- HDU 3982 半平面交+圆与多边形面积交
- HDU 3982 (半平面交 多边形和圆面积交)
- bzoj2618 凸多边形 半平面交
- BZOJ2618 凸多边形 半平面交
- POJ 1279 Art Gallery 半平面交 + 多边形面积
- 计算多边形核的面积、半平面交(poj1279)
- hdu 3982 Harry Potter and J.K.Rowling(半平面交+求凸多边形和圆的面积交)
- 解决 WebClient 405 错误的方法
- HDU 3613 Best Reward(扩展KMP)
- 用Delphi即时判断当前的网络的连接方式
- 算法导论—栈和队列
- Android开发之AutoCompleteTextView控件
- [BZOJ 2618][CQOI 2006]凸多边形(半平面交+三角剖分求多边形面积)
- 【内部排序】一:直接插入排序(Straight Insertion Sorting)的多种实现(不断优化+源码)
- 129:Sum Root to Leaf Numbers【树】【DFS】
- 搜索引擎对关键字的识辨
- jquery 互转 javascript
- 浅谈NFC
- Storm介绍
- 黑马程序员---Java之this的用法
- android使用另一个Android项目作为library