JDFZOJ 1005 多边形面积 扫描线
来源:互联网 发布:淘宝内衣买家秀 编辑:程序博客网 时间:2024/05/18 22:39
题目大意:给出N个凸多边形,求这些多边形的面积并。
思路:N只有不到10,乱搞就可以。还有一种更优的解法,似乎只需要O(n^2logn)的时间就可以解决。但是我并不会,想了解的参照:http://wyfcyx.is-programmer.com/posts/80378.html
下面说乱搞的思路。由于都是凸多边形,那么任意一条垂直于x轴的直线在多边形内的区域一定是一条线段(或者什么都没有),那么我们将所有多边形按照梯形进行剖分,求出每个部分的梯形中腰长度并就可以算出总的面积了。
题目网址见:http://oj.jdfz.com.cn:8081/oldoj/problem.php?id=1005
CODE:
#define _CRT_SECURE_NO_WARNINGS #include <cmath>#include <cstdio>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>#define MAX 20#define EPS 1e-8using namespace std;#define max(a,b) ((a) > (b) ? (a):(b))#define min(a,b) ((a) < (b) ? (a):(b))#define INRANGE(x,y,c) ((c <= y && c >= x) || (c <= x && c >= y)) struct Point{ double x,y; Point(double _,double __):x(_),y(__) {} Point() {} Point operator +(const Point &a)const { return Point(x + a.x,y + a.y); } Point operator -(const Point &a)const { return Point(x - a.x,y - a.y); } Point operator *(double a)const { return Point(x * a,y * a); } void Read() { scanf("%lf%lf",&x,&y); }}temp[1010]; inline double Calc(const Point &p1,const Point &p2){ return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));} inline double Cross(const Point &p1,const Point &p2){ return p1.x * p2.y - p1.y * p2.x;} struct Segment{ Point p1,p2,v; Segment(Point _,Point __,Point ___):p1(_),p2(__),v(___) {} Segment() {} bool OnSegment(const Point &p) { if(p1.x == p2.x) return INRANGE(p1.y,p2.y,p.y); return INRANGE(p1.x,p2.x,p.x); }}*src[MAX][1010],save[MAX * 1010];int cnt_seg; struct Interval{ double x,y; Interval(double _,double __):x(_),y(__) {} Interval() {} bool operator <(const Interval &a)const { if(x == a.x) return y < a.y; return x < a.x; }}interval[MAX * 1010]; inline Point GetIntersection(const Segment &l1,const Segment &l2){ Point u = l1.p1 - l2.p1; double t = Cross(l2.v,u) / Cross(l1.v,l2.v); return l1.p1 + l1.v * t;} inline Segment *MakeSegment(const Point &p1,const Point &p2){ save[++cnt_seg] = Segment(p1,p2,p2 - p1); return &save[cnt_seg];} inline Interval GetInterval(Segment *src[],double x){ Interval re(0,0); for(int i = 1; src[i] != NULL; ++i) { Point intersection = GetIntersection(*src[i],Segment(Point(x,0),Point(x,0),Point(0,1))); if(src[i]->OnSegment(intersection)) { if(!re.x) re.x = intersection.y; else re.y = intersection.y; } } if(re.x > re.y) swap(re.x,re.y); return re;} int cnt;double divide[1010 * 1010]; int main(){ cin >> cnt; for(int points,i = 1; i <= cnt; ++i) { scanf("%d",&points); for(int j = 1; j <= points; ++j) temp[j].Read(); for(int j = 1; j < points; ++j) src[i][j] = MakeSegment(temp[j],temp[j + 1]); src[i][points] = MakeSegment(temp[points],temp[1]); } int divides = 0; for(int i = 1; i <= cnt_seg; ++i) for(int j = i + 1; j <= cnt_seg; ++j) { if(fabs(Cross(save[i].v,save[j].v)) < EPS) continue; Point intersection = GetIntersection(save[i],save[j]); divide[++divides] = intersection.x; } sort(divide + 1,divide + divides + 1); double area = .0; for(int i = 1; i < divides; ++i) { double x = (divide[i + 1] + divide[i]) / 2; int intervals = 0; for(int j = 1; j <= cnt; ++j) interval[++intervals] = GetInterval(src[j],x); sort(interval + 1,interval + intervals + 1); double now = .0,l = interval[1].x,r = interval[1].y; for(int j = 2; j <= intervals; ++j) if(interval[j].x <= r) r = max(r,interval[j].y); else { now += r - l; l = interval[j].x; r = interval[j].y; } now += r - l; area += now * (divide[i + 1] - divide[i]); } cout << fixed << setprecision(3) << area << endl; return 0;}
0 0
- JDFZOJ 1005 多边形面积 扫描线
- 多边形扫描线算法
- 多边形面积
- 多边形面积
- 扫描线法填充多边形
- 扫描线矩形面积交
- 【多边形面积】求多边形的面积 pol
- 扫描线-通用多边形填充算法
- 扫描线算法判断多边形是否合法
- OpenGL实现多边形扫描转换的扫描线算法
- FAFU-1398 面积 矩形面积并 线段树+扫描线
- 重叠面积--扫描线 hdu1255 覆盖的面积
- hdu1255 覆盖的面积(矩形面积交+扫描线)
- 计算多边形面积 绿色
- 求不规则多边形面积
- 多边形面积计算
- 多边形面积公式
- 计算多边形的面积
- 我眼中的吉胜
- 也许 DOM 不是答案
- 在线虚拟主机
- Java 加解密技术系列之 BASE64
- 作为人才我们为什么要和几个猎头保持良好的关系?
- JDFZOJ 1005 多边形面积 扫描线
- 解决dialog中edittext点击两次才响应事件的问题
- 【生活感想】今天的两个奇妙的想法,连屏手机和联网图书馆
- java之单用户登录
- 创业三个月总结---记录这三个月的酸甜苦辣咸!!!
- java之单点登录
- 深度学习初识(1)
- Swift语言中问号 ? 和 感叹号 ! 的作用
- 通过sed和awk获取集群最新挂掉的DataNode信息