2018.07.03 POJ 1279Art Gallery(半平面交)
Art Gallery
Time Limit: 1000MS Memory Limit: 10000K
Description
The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2.
Input
The number of tasks T that your program have to solve will be on the first row of the input file. Input data for each task start with an integer N, 5 <= N <= 1500. Each of the next N rows of the input will contain the co-ordinates of a vertex of the polygon ? two integers that fit in 16-bit integer type, separated by a single space. Following the row with the co-ordinates of the last vertex for the task comes the line with the number of vertices for the next test and so on.
Output
For each test you must write on one line the required surface - a number with exactly two digits after the decimal point (the number should be rounded to the second digit after the decimal point).
Sample Input
1
7
0 0
4 4
4 7
9 7
13 -1
8 -6
4 -4
Sample Output
80.00
Source
Southeastern Europe 2002
这又是一道基础的计算几何题,准确的说,这就是求半平面交的裸板,这也是本蒟蒻第一次写半平面交这个东西。这里简单提一下半平面交的求法吧。
首先,我们将所有半平面按照极角排序,然后用类似极角排序求凸包的方法来求半平面交,但区别是求凸包只需要使用一个栈,而现在我们需要维护的是一个双端队列。为什么呢?因为如果我们当前再放入一个半平面,它会对队首和队尾的半平面都产生影响(没懂的可以画个图感受一下)。什么时候我们会从队列中弹出半平面中呢?显然需要判断前两个半平面的交点和该半平面的关系,如果点在半平面右侧就弹出直到弹不动或者队列为空为止。然后实现时会有一些比较烦的细节,但总的来说写起来还是比较愉快的。
我们要注意这道题的一些坑点:首先点可能按顺时针或者逆时针给出,这样的话我们要先按一定顺序求一遍原多边形的面积来调整每个半平面的方向。其次,本蒟蒻在POJ上一直WA,对着其他大佬的代码改也过不了,最后无奈将printf函数中的lf改成了f就过了,这个真的是玄学错误了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1.0e-12
#define N 1505
using namespace std;
int t,n,q[N];
struct point{double x,y;}p[N];
struct line{point a,b;double poa;}l[N];
inline point operator-(point a,point b){return point{a.x-b.x,a.y-b.y};}
inline double cross(point a,point b){return a.x*b.y-b.x*a.y;}
inline point across(line a,line b){
double a1=cross(b.b-a.a,b.a-a.a),a2=cross(b.a-a.b,b.b-a.b);
return point{(a2*a.a.x+a1*a.b.x)/(a2+a1),(a2*a.a.y+a1*a.b.y)/(a2+a1)};
}
inline bool check(point a,line b){return cross(a-b.a,b.b-b.a)>0;}
inline bool cmp(line a,line b){
if(fabs(a.poa-b.poa)<eps)return cross(a.b-b.a,b.b-b.a)<0;
return a.poa<b.poa;
}
inline double solve(){
sort(l+1,l+n+1,cmp);
int siz=0,head=1,tail=1;
for(int i=1;i<=n;++i)
if(fabs(l[i-1].poa-l[i].poa)>eps)l[++siz]=l[i];
q[1]=1;
for(int i=2;i<=siz;++i){
while(head<tail&&check(across(l[q[tail-1]],l[q[tail]]),l[i]))--tail;
while(head<tail&&check(across(l[q[head]],l[q[head+1]]),l[i]))++head;
q[++tail]=i;
}
while(head<tail&&check(across(l[q[tail-1]],l[q[tail]]),l[q[head]]))--tail;
while(head<tail&&check(across(l[q[head]],l[q[head+1]]),l[q[tail]]))++head;
if(tail-head<=1)return 0.00;
else{
for(int i=head;i<tail;++i)p[i-head+1]=across(l[q[i]],l[q[i+1]]);
p[tail-head+1]=across(l[q[tail]],l[q[head]]);
double ans=0.0;
for(int i=1;i<=tail-head;++i)ans+=cross(p[i],p[i+1]);
ans+=cross(p[tail-head+1],p[1]);
return ans/2.0;
}
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%lf%lf",&p[i].x,&p[i].y);
double area=0.0;
for(int i=1;i<n;++i){
l[i].a=p[i],l[i].b=p[i+1];
area+=cross(p[i],p[i+1]);
}
l[n].a=p[n],l[n].b=p[1];
area+=cross(p[n],p[1]);
if(area<0.0)for(int i=1;i<=n;++i)swap(l[i].a,l[i].b);
for(int i=1;i<=n;++i)l[i].poa=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
printf("%.2f\n",solve());
}
return 0;
}
2018.07.03 POJ 1279Art Gallery(半平面交)的更多相关文章
- 2018.07.03 POJ 2318 TOYS(二分+简单计算几何)
TOYS Time Limit: 2000MS Memory Limit: 65536K Description Calculate the number of toys that land in e ...
- 2018.07.03 POJ 2653 Pick-up sticks(简单计算几何)
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Description Stan has n sticks of various leng ...
- 2018.07.03 POJ 3348 Cows(凸包)
Cows Time Limit: 2000MS Memory Limit: 65536K Description Your friend to the south is interested in b ...
- POJ 1279 Art Gallery 半平面交/多边形求核
http://poj.org/problem?id=1279 顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题 这里的半平面交是O(n^2)的算法...比较逗比.. ...
- POJ 1279 Art Gallery 半平面交求多边形核
第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内 ...
- poj 3335(半平面交)
链接:http://poj.org/problem?id=3335 //大牛们常说的测模板题 ------------------------------------------------- ...
- POJ 1755 Triathlon [半平面交 线性规划]
Triathlon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6912 Accepted: 1790 Descrip ...
- 2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln, ...
- POJ 1279 Art Gallery(半平面交)
题目链接 回忆了一下,半平面交,整理了一下模版. #include <cstdio> #include <cstring> #include <string> #i ...
随机推荐
- css之单边阴影
css之单边阴影 需求:在网上找的其他博客上说单边阴影需要牺牲掉模糊,实际上牺牲掉模糊直接用border不就好了 效果: 原理: 1.在左边的外阴影就是右边的内阴影 2.将box-shadow写在be ...
- rabbitmq /usr/lib/rabbitmq/bin/rabbitmq-server: line 85: erl: command not found
问题描述:在使用命令/sbin/service rabbitmq-server start启动Rabbitmq时,报: Job for rabbitmq-server.service failed b ...
- fabric应用
安装: easy_install fabric 或 pip install fabric 验证: #python >>> import fabric 有时候我们可以直接使用命令行的 ...
- scala -- 柯里化
柯里化 柯里化是把接受多个参数的函数,变成接受一个单一参数的函数.并且返回接受剩余参数和返回结果的新函数. 就是一个逐次消元的过程. 当把函数的元全消掉,就得到了值. 值就是零元函数. 二元函数 f( ...
- orientdb 学习
简介 OrientDB 是一款 NoSQL 数据库.是一种文档-图数据库.即:既具有文档数据库的特性,又具有图数据库的功能. 端口 2424 OrientDB 监听 二进制 访问的的端口 (即:通过 ...
- 第一个struct2程序(2)
第三步 需要使用ActionForm了.在Struts1.x中,必须要单独建立一个ActionForm类(或是定义一个动作Form),而在Struts2中ActionForm和Action已经二合一了 ...
- mysql 列转行
第一种方法:使用序列化表的方法实现列转行 第一种方法:使用UNION的方法实现列转行 第二种方法:使用序列化表的方法实现列转行
- Eclipse中Git插件使用技巧:还原文件
如果修改了某个文件并未提交至本地库(add index),那么怎么还原呢?Git插件中并不像Svn插件直接提供有还原方式.其实无论是否提交至本地库或者远程库,还原操作的本质都是将文件的当前版本还原至之 ...
- html标签对应的英文原文(转载)
标签 对应英文 说明 <!--> / 注释 <!DOCTYPE> document type 文档类型 <a> anchor 超链接 <abbr> a ...
- socket接口详解
1. socket概述 socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在Unix一切 ...