POJ 1279 Art Gallery 半平面交求多边形核
第一道半平面交,只会写N^2。
将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解。
半平面交其实就是对一系列的不等式组进行求解可行解。
如果某点在直线右侧,说明那个点在区域内,否则出现在左边,就可能会有交点,将交点求出加入。
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
using namespace std; const int MAXN = ;
const double eps = 1e-; struct POINT{
double x;
double y;
POINT() : x(), y() {};
POINT(double _x_, double _y_) : x(_x_), y(_y_) {};
}; struct LINE{
POINT a;
POINT b;
LINE() {};
LINE(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};
}; POINT point[MAXN];//记录最开始的多边形
POINT temp[MAXN]; //临时保存新切割的多边形
POINT ans[MAXN]; //保存新切割出的多边形
LINE lline;
int n,m;//n的原先的点数,m是新切割出的多边形的点数 void Coefficient(const LINE & L, double & A, double & B, double & C){
A = L.b.y - L.a.y;
B = L.a.x - L.b.x;
C = L.b.x * L.a.y - L.a.x * L.b.y;
} double Cross(const POINT & a, const POINT & b, const POINT &o){
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
} POINT Intersection(const LINE & A, const LINE & B){
double A1, B1, C1;
double A2, B2, C2;
Coefficient(A, A1, B1, C1);
Coefficient(B, A2, B2, C2);
POINT temp_point(, );
temp_point.x = -(B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
temp_point.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
return temp_point;
} //求面积,正为顺时针,和叉积写法有关
double PointArea(POINT p[],int n){
double area = ;
for(int i = ; i < n; ++i)
area += Cross(p[], p[i], p[i+]);
return -area / 2.0;
} void Cut(){ //用直线ax+by+c==0切割多边形
int cut_m = , i;
double a, b, c;
Coefficient(lline, a, b, c);
for(i = ; i <= m; ++i){
if(a * ans[i].x + b*ans[i].y + c >= ) //题目是顺时钟给出点的,所以一个点在直线右边的话,那么带入值就会大于等于0
temp[++cut_m] = ans[i]; //说明这个点还在切割后的多边形内,将其保留
else{
if(a * ans[i - ].x + b * ans[i - ].y + c > ){ //该点不在多边形内,但是它和它相邻的点构成直线与
LINE line1(ans[i - ], ans[i]); //ax+by+c==0所构成的交点可能在新切割出的多边形内,
temp[++cut_m] = Intersection(lline, line1); //所以保留交点
}
if(a * ans[i + ].x + b * ans[i + ].y + c > ){
LINE line1(ans[i + ], ans[i]);
temp[++cut_m] = Intersection(lline, line1); //所以保留交点
}
}
}
for(i = ; i <= cut_m; ++i) ans[i] = temp[i];
ans[cut_m + ] = temp[];
ans[] = temp[cut_m];
m = cut_m;
} void solve(){
int i;
point[] = point[n];
point[n+] = point[];
for(i = ; i <= n + ; ++i){
ans[i] = point[i];
}
m = n;
for(i = ;i <= n; ++i){
lline.a = point[i];
lline.b = point[i + ]; //根据point[i]和point[i+1]确定直线ax+by+c==0
Cut(); //用直线ax+by+c==0切割多边形
}
printf("%.2f\n",Abs(PointArea(ans,m)));
} int main(){
int caseNum,i;
scanf("%d",&caseNum);
while(caseNum--){
scanf("%d",&n);
for(i = ; i <= n; ++i){
scanf("%lf%lf",&point[i].x,&point[i].y);
}
solve();
}
return ;
}
POJ 1279 Art Gallery 半平面交求多边形核的更多相关文章
- POJ 1279 Art Gallery 半平面交/多边形求核
http://poj.org/problem?id=1279 顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题 这里的半平面交是O(n^2)的算法...比较逗比.. ...
- 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 3335 Rotating Scoreboard(半平面交求多边形核)
题目链接 题意 : 给你一个多边形,问你在多边形内部是否存在这样的点,使得这个点能够看到任何在多边形边界上的点. 思路 : 半平面交求多边形内核. 半平面交资料 关于求多边形内核的算法 什么是多边形的 ...
- 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 (Half Plane Intersection)
1279 -- Art Gallery 还是半平面交的问题,要求求出多边形中可以观察到多边形所有边的位置区域的面积.其实就是把每一条边看作有向直线然后套用半平面交.这题在输入的时候应该用多边形的有向面 ...
- POJ 3335 Rotating Scoreboard 半平面交求核
LINK 题意:给出一个多边形,求是否存在核. 思路:比较裸的题,要注意的是求系数和交点时的x和y坐标不要搞混...判断核的顶点数是否大于1就行了 /** @Date : 2017-07-20 19: ...
随机推荐
- pexpect-pxssh-登陆Linux-执行命令
#!/usr/bin/python import pexpect import pxssh try: remote=pxssh.pxssh() hostname=raw_input('hostname ...
- poj 3304 计算几何
大意: 是否存在一条直线,使所有线段在直线上的投影至少交与一点 思路: 转换为是否存在一条直线与所有的线段相交,做这条直线的垂线,那么垂线即为所求 **/ #include <iostream& ...
- java时间验证工具
可以验证2014-02-21这种错误
- jQuery json数据处理
一种是使用jQuery的ajax函数 另一种是使用getJSON函数 使用ajax函数的时候 对于返回值类型dataType 亲自指定为json格式 就无需自己手动处理格式 $.ajax({ url ...
- Windows10 上运行Ubuntu Bash
Windows10 上运行Ubuntu Bash 2016年4月6日,Windows 10 Insider Preview 发布的版本 14316,添加了Ubuntu Bash,在Windows上提供 ...
- CI引入外部javascript和css
假定baseurl 为 $config['base_url']='http://localhost/codeigniter/'; 调用 <link rel="stylesheet&qu ...
- Laravel + Xdebug 时需要注意的问题
[平台环境]64bit Win7 + Wamp2.5 (php 5.5, Apache 2.4.9) [Xdebug版本]php_xdebug-2.2.5-5.5-vc11-x86_64.dll 配置 ...
- poj 3630 Phone List(字典树)
题目链接: http://poj.org/problem?id=3630 思路分析: 求在字符串中是否存在某个字符串为另一字符串的前缀: 即对于某个字符串而言,其是否为某个字符串的前缀,或存在某个其先 ...
- hdu1715 大菲波数
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1715 Problem ...
- ORACLE 使用RMAN管理归档日志 archived log
oracle 归档日志通常使用rman进行管理,作为备份集的一部分 正常情况下,可以根据方法删除 1 过期策略 crosscheck archivelog all; delete expired ar ...