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 ...
随机推荐
- HTML5 ES6 语法基础
// 解构赋值 let [a, b, c, [s,e],d] = ["aa", "bb", "cc", [12, 23], "dd ...
- JS实现让滚轮控制网页头部显示与隐藏
在很多网站中都有鼠标网上滚动头部就会滑出,继续往下滚动就会隐藏,下面看看实现方法 scroll(); function scroll(){// 入口方法 这个方法是获取事件的兼容,获取delta -- ...
- c++builder XE6 Remote Debuger 远程调试
1.远程目标机器 安装D:\Program Files (x86)\Borland\Remote Debugger\20,没有光盘从已安装的xe6电脑上Bin目录下拷贝文件 bccide.dll bo ...
- Activity服务类-4 HistoryService服务类
一共个方法15个方法 用于查询历史工作流信息1.创建查询(7个方法)//创建一个新的编程查询来搜索{@link HistoricProcessInstance}.HistoricProcessInst ...
- ABAP-年月期间搜索帮助
selection-screen begin of block block1 with frame title text-. parameters:p_mon1 like s031-spmon, p_ ...
- ubuntu查询可用安装包
当使用apt-get install packages时,如果不知道安装包的具体名称,可以使用关键字进行搜索,使用:apt-cache search keywords
- java 观察者模式 与spring配置
一.Observer模式的意图: 在对象的内部状态发生变化时,自动通知外部对象进行响应. 二.Observer模式的构成: ·被观察者:内部状态有可能被改变,而且又需要通知外部的对象 ·观察者:需要对 ...
- Rsync+sersync实现数据实时同步
前言: 一.为什么要用Rsync+sersync架构? 1.sersync是基于Inotify开发的,类似于Inotify-tools的工具 2.sersync可以记录下被监听目录中发生变化的(包括增 ...
- Hibernate merge和update的区别
今天做了个测试,写了个测试用例来看看merge与update时控制台打印出来的日志有什么不一样.实体bean很简单,就id和name两个字段,接下来分别给出以下几种测试情形的控制台日志内容: 1. 数 ...
- 吴裕雄 数据挖掘与分析案例实战(10)——KNN模型的应用
# 导入第三方包import pandas as pd # 导入数据Knowledge = pd.read_excel(r'F:\\python_Data_analysis_and_mining\\1 ...