poj 1279 Art Gallery (Half Plane Intersection)
还是半平面交的问题,要求求出多边形中可以观察到多边形所有边的位置区域的面积。其实就是把每一条边看作有向直线然后套用半平面交。这题在输入的时候应该用多边形的有向面积来判断输入的顺序是顺时针的还是逆时针的。
对于半平面交问题,要注意最后半平面返回的是多少个点。对于小于3个点的情况应该直接返回结果,避免计算过程中产生错误。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath> using namespace std; struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
} ;
template<class T> T sqr(T x) { return x * x;}
typedef Point Vec;
Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);} const double EPS = 1e-;
const double PI = acos(-1.0);
inline int sgn(double x) { return (x > EPS) - (x < -EPS);} inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
inline double toRad(double deg) { return deg / 180.0 * PI;}
inline double angle(Vec v) { return atan2(v.y, v.x);}
inline Vec vecUnit(Vec x) { return x / vecLen(x);}
inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);} const int N = ;
struct DLine {
Point p;
Vec v;
double ang;
DLine() {}
DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
bool operator < (DLine L) const { return ang < L.ang;}
} dl[N];
Point pt[N]; inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > ;}
Point dLineIntersect(DLine a, DLine b) {
Vec u = a.p - b.p;
double t = crossDet(b.v, u) / crossDet(a.v, b.v);
return a.p + a.v * t;
} struct Poly {
vector<Point> pt;
Poly() { pt.clear();}
~Poly() {}
Poly(vector<Point> &pt) : pt(pt) {}
Point operator [] (int x) { return pt[x];}
int size() { return pt.size();}
double area() {
double ret = 0.0;
int sz = pt.size();
pt.push_back(pt[]);
for (int i = ; i <= sz; i++) ret += crossDet(pt[i], pt[i - ]);
pt.pop_back();
return fabs(ret / 2.0);
}
} ; Poly halfPlane(DLine *L, int n) {
Poly ret = Poly();
sort(L, L + n);
int fi, la;
Point *p = new Point[n];
DLine *q = new DLine[n];
q[fi = la = ] = L[];
for (int i = ; i < n; i++) {
while (fi < la && !onLeft(L[i], p[la - ])) la--;
while (fi < la && !onLeft(L[i], p[fi])) fi++;
q[++la] = L[i];
if (sgn(crossDet(q[la].v, q[la - ].v)) == ) {
la--;
if (onLeft(q[la], L[i].p)) q[la] = L[i];
}
if (fi < la) p[la - ] = dLineIntersect(q[la - ], q[la]);
}
while (fi < la && !onLeft(q[fi], p[la - ])) la--;
if (la < fi) return ret;
p[la] = dLineIntersect(q[la], q[fi]);
for (int i = fi; i <= la; i++) ret.pt.push_back(p[i]);
return ret;
} bool isClockwise(Point *pt, int n) {
double sum = 0.0;
pt[n] = pt[];
Point O = Point(0.0, 0.0);
for (int i = ; i < n; i++) {
sum += crossDet(O, pt[i], pt[i + ]);
}
return sum < ;
} int main() {
int T, n;
cin >> T;
while (T-- && cin >> n) {
for (int i = ; i < n; i++) cin >> pt[i].x >> pt[i].y;
pt[n] = pt[];
if (isClockwise(pt, n)) for (int i = ; i < n; i++) dl[i] = DLine(pt[i + ], pt[i] - pt[i + ]);
else for (int i = ; i < n; i++) dl[i] = DLine(pt[i], pt[i + ] - pt[i]);
Poly tmp = halfPlane(dl, n);
if (tmp.size() >= ) printf("%.2f\n", tmp.area());
else puts("0.00");
}
return ;
}
——written by Lyon
poj 1279 Art Gallery (Half Plane Intersection)的更多相关文章
- poj 1279 Art Gallery - 求多边形核的面积
/* poj 1279 Art Gallery - 求多边形核的面积 */ #include<stdio.h> #include<math.h> #include <al ...
- poj 1279 -- Art Gallery (半平面交)
鏈接:http://poj.org/problem?id=1279 Art Gallery Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- POJ 1279 Art Gallery 半平面交/多边形求核
http://poj.org/problem?id=1279 顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题 这里的半平面交是O(n^2)的算法...比较逗比.. ...
- POJ 1279 Art Gallery 半平面交求多边形核
第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内 ...
- POJ 1279 Art Gallery 半平面交 多边形的核
题意:求多边形的核的面积 套模板即可 #include <iostream> #include <cstdio> #include <cmath> #define ...
- POJ 1279 Art Gallery(半平面交)
题目链接 回忆了一下,半平面交,整理了一下模版. #include <cstdio> #include <cstring> #include <string> #i ...
- POJ 1279 Art Gallery(半平面交求多边形核的面积)
题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> ...
- [POJ]1279: Art Gallery
题目大意:有一个N边形展馆,问展馆内有多少地方可以看到所有墙壁.(N<=1500) 思路:模板题,半平面交求出多边形的核后计算核的面积. #include<cstdio> #incl ...
- POJ 1279 Art Gallery【半平面交】(求多边形的核)(模板题)
<题目链接> 题目大意: 按顺时针顺序给出一个N边形,求N边形的核的面积. (多边形的核:它是平面简单多边形的核是该多边形内部的一个点集该点集中任意一点与多边形边界上一点的连线都处于这个多 ...
随机推荐
- JS 获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...
- web前端学习(三)css学习笔记部分(7)-- 文字和字体相关样式、盒子相关样式、背景与边框相关样式
12. 文字和字体相关样式 12.1 CSS3 给文字添加阴影 使用 text-shadow 属性给页面上的文字添加阴影效果,text-shadow 属性是在CSS2中定义的,在 CSS2.1 中 ...
- ecshop二次开发之百度地图
案例效果展示: 代码实现: 1.在ecshop后台找到文章管理->文章分类->添加文章分类,添加一个顶级分类,叫做"合作单位",并且让其显示在导航栏.如下图: 1.在e ...
- Least Common Multiple (最小公倍数,先除再乘)
思路: 求第一个和第二个元素的最小公倍数,然后拿求得的最小公倍数和第三个元素求最小公倍数,继续下去,直到没有元素 注意:通过最大公约数求最小公倍数的时候,先除再乘,避免溢出 #include ...
- 替换文本:将文本文件中的所有src替换为dst
题意: 将文本文件中的所有src替换为dst 方法一:使用String import java.io.File; import java.io.FileNotFoundException; impor ...
- 常用命令3-文件搜索命令1-locate
新建文件搜索不到,是因为查询是从数据库里查询的,然后数据库是一天后才更新,但是可以强制更新. 优点:能进行模糊搜索. 在tmp目录下创建一个文件,发现,在root家目录下搜不到.是因为配置文件原因. ...
- 【《Objective-C基础教程 》笔记】(八)OC的基本事实和OC杂七杂八的疑问
一.疑问 1.成员变量.实例变量.局部变量的差别和联系,在訪问.继承上怎样表现. 2.属性@property 和 {变量列表} 是否同样.有什么不同. 3.类方法.类成员.类属性:实例方法.实例变量. ...
- 什么? 1XIN = 21BTC
什么? 1XIN = 21BTC 最初看到这个标题,我还回去考证一下. 原来是 Mixin Network 的宣传广告. BTC 是多少? 2100万枚. XIN 是 100 万枚. 所以才有了 1X ...
- 关于PHP学习--摘自知乎
主要是学框架(其实也没啥可学的).数据库.服务器.linux. 所以我推荐apache/nginx文档,框架的文档,mysql的文档,linux使用说明,等等等等. PHP: PHP 手册MySQL ...
- HDU4251-The Famous ICPC Team Again(划分树)
Problem Description When Mr. B, Mr. G and Mr. M were preparing for the 2012 ACM-ICPC World Final Con ...