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边形的核的面积. (多边形的核:它是平面简单多边形的核是该多边形内部的一个点集该点集中任意一点与多边形边界上一点的连线都处于这个多 ...
随机推荐
- JavaScript远程调用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- webpack学习之—— Configuration(配置)
你可能已经注意到,很少有 webpack 配置看起来很完全相同.这是因为 webpack 的配置文件,是导出一个对象的 JavaScript 文件.此对象,由 webpack 根据对象定义的属性进行解 ...
- GitHub的注册与使用
1. 注册账号: 地址: https://github.com/输入账号.邮箱.密码,然后点击注册按钮. 2. 初始设置 注册完成后,选择Free免费账号完成设置 3.验证账号 新建一个仓库 发现邮箱 ...
- 【JZOJ4711】【NOIP2016提高A组模拟8.17】Binary
题目描述 输入 输出 样例输入 6 6 8 9 1 13 9 3 1 4 5 2 6 9 1 3 7 2 7 7 1 6 1 2 11 13 样例输出 45 19 21 数据范围 解法 40%暴力即可 ...
- Python学习笔记(二)使用Sublime Text编写简单的Python程序()
一.使用Sublime Text编写Python 1.点击“文件” →”新建文件“ 2.点击”文件“→”保存“,并保存为.py文件 此时已经创建好Python文件了,接下来就可以编写Python程序了 ...
- Codeforces Round #275 (Div. 2) A. Counterexample【数论/最大公约数】
A. Counterexample time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Vue.之. 动态设置按钮Disabled
Vue.之. 动态设置按钮Disabled 按钮代码如下: 添加了一个 属性 :disabled="isAble" ,控制:更新按钮.重置按钮 <el-form- ...
- [Vue CLI 3] 配置解析之 css.extract
大家还记得我们在老版本中,对于线上环境配置中会把所有的 css 多打成一个文件: 核心是使用了插件 extract-text-webpack-plugin,方式如下: 第一步都是加载插件 const ...
- python控制台输出带颜色文字的方法
目地:提高重要信息的可读性,方便用户阅读了. 书写格式如下: #格式: 设置颜色开始 :\033[显示方式;前景色;背景色m #说明: 前景色 背景色 颜色 --------------------- ...
- Servlet会话跟踪和Cookies及HttpSession会话
会话只是指一段指定的时间间隔. 会话跟踪是维护用户状态(数据)的一种方式.它也被称为servlet中的会话管理. Http协议是一个无状态的,所以我们需要使用会话跟踪技术来维护用户状态. 每次用户请求 ...