题意:求多边形的内核,即:在多边形内部找到某个点,使得从这个点能不受阻碍地看到多边形的所有位置.

只要能看到所有的边,就能看到所有的位置.那么如果我们能够在多边形的内部的点x看到某条边AB,这个点x一定在AB的”内侧”,如果按逆时针方向给出多边形的所有顶点并假设从A到B是逆时针行走,”内侧”就是指有向直线A->B的左侧,那么多边形的每条边对应了一个半平面,要想看见这条边必须保证x在这个半平面内.而且,只要对于每条边x都在这条边的左侧,那么x就是一个可行的点,能够看到整个多边形.

这个结论的必要性是显然的(如果x在某条边的右侧,那么一定看不到这条边)

充分性也可以证:假如存在某个点是x看不见的,那么从x向这个点连线,一定会穿过偶数条多边形的边(因为每穿过一条边就从多边形的内部走到外部或者从外部走到内部,而起点终点都在内部),那么这些边一定是有一半从边的左侧穿到右侧(即从内到外),一半从边的右侧穿到左侧(即从外到内).也就是说,如果存在一个x看不见的点,就一定存在一条多边形的边使得x在这条边的右侧,于是如果找不到一条多边形的边使得x在这条边的右侧,就不存在x看不见的点,于是这个结论具有充分性.

那么我们对n条边求一下半平面交,判段是否非空即可.注意这里结果是一个点或一个线段时也判作有解,我的方法是把多边形的每条边都向多边形外部沿法向量方向平移一点,这样点和线段就都变成了面积不为0的区域,避免了边界讨论.

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=;
const double eps=1e-;
int cmp(double x){return x<-eps?-:x>eps;}
struct point{
double x,y;point(){}
point(double a,double b){x=a;y=b;}
void read(){scanf("%lf%lf",&x,&y);}
}P[maxn],p[maxn];
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
double cross(point a,point b){return a.x*b.y-a.y*b.x;}
struct line{
point s,d;double arg;
bool operator <(const line &B)const{return cmp(arg-B.arg)==-;}
line(){}
line(point a,point b){s=a;d=b;arg=atan2(d.y,d.x);}
void output(){
printf("(%f,%f)+(%f,%f)\n",s.x,s.y,d.x,d.y);
}
}L[maxn],q[maxn];
int n;
bool onleft(line A,point B){
return cmp(cross(A.d,B-A.s))>;
}
point mult(double t,point A){
return point(t*A.x,t*A.y);
}
point intersect(line A,line B){
double t=cross(B.d,A.s-B.s)/cross(A.d,B.d);
return A.s+mult(t,A.d);
}
point rot(point A,double arg){
return point(A.x*cos(arg)-A.y*sin(arg),A.x*sin(arg)+A.y*cos(arg));
}
int HPI(){
sort(L,L+n);
int head,tail;head=tail=;q[tail++]=L[];
for(int i=;i<n;++i){
while(head+<tail&&!onleft(L[i],p[tail-]))tail--;
while(head+<tail&&!onleft(L[i],p[head])) head++;
q[tail++]=L[i];
if(head+<tail&&cmp(cross(q[tail-].d,q[tail-].d))==){
tail--;
if(onleft(q[tail-],L[i].s))q[tail-]=L[i];
}
if(head+<tail)p[tail-]=intersect(q[tail-],q[tail-]);
}
while(head+<tail&&!onleft(q[head],p[tail-]))tail--;
// q[head].output();q[head+1].output();
if(tail-head<=)return ;
else return ;
}
point normal(point A){return point(-A.y,A.x);}
point operator *(const double &t,const point &A){return point(A.x*t,A.y*t);}
int main(){
int tests=;
while(scanf("%d",&n),n!=){
for(int i=;i<n;++i)P[i].read();P[n]=P[];
for(int i=;i<n;++i)L[i]=line(P[i]-eps*normal(P[i]-P[i+]),P[i]-P[i+]);
if(HPI())printf("Floor #%d\nSurveillance is possible.\n",++tests);
else printf("Floor #%d\nSurveillance is impossible.\n",++tests);
printf("\n");
}
return ;
}

poj1474 Video Surveillance的更多相关文章

  1. POJ1474 Video Surveillance(半平面交)

    求多边形核的存在性,过了这题但是过不了另一题的,不知道是模板的问题还是什么,但是这个模板还是可以过绝大部分的题的... #pragma warning(disable:4996) #include & ...

  2. POJ1474:Video Surveillance(求多边形的核)(占位)

    A friend of yours has taken the job of security officer at the Star-Buy Company, a famous depart- me ...

  3. poj 1474 Video Surveillance - 求多边形有没有核

    /* poj 1474 Video Surveillance - 求多边形有没有核 */ #include <stdio.h> #include<math.h> const d ...

  4. poj 1474 Video Surveillance (半平面交)

    链接:http://poj.org/problem?id=1474 Video Surveillance Time Limit: 1000MS   Memory Limit: 10000K Total ...

  5. POJ1474:Video Surveillance——题解

    http://poj.org/problem?id=1474 题目大意:给按照顺时针序的多边形顶点,问其是否有内核. —————————————————————————————— (和上道题目一模一样 ...

  6. POJ 1474 Video Surveillance(半平面交)

    题目链接 2Y,模版抄错了一点. #include <cstdio> #include <cstring> #include <string> #include & ...

  7. Video Surveillance - POJ 1474(判断是否存在内核)

    题目大意:询问是否在家里装一个监视器就可以监控所有的角落. 分析:赤裸裸的判断多边形内核题目. 代码如下: #include<iostream> #include<string.h& ...

  8. ●poj 1474 Video Surveillance

    题链: http://poj.org/problem?id=1474 题解: 计算几何,半平面交 半平面交裸题,快要恶心死我啦... (了无数次之后,一怒之下把onleft改为onright,然后还加 ...

  9. POJ - 1474 :Video Surveillance (半平面交-求核)

    pro:顺时针给定多边形,问是否可以放一个监控,可以监控到所有地方,即问是否存在多边形的核. 此题如果两点在同一边界上(且没有被隔段),也可以相互看到. sol:求多边形是否有核.先给直线按角度排序, ...

随机推荐

  1. spring作用

    在SSH框假中spring充当了管理容器的角色.我们都知道hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句.Struts是用来 ...

  2. logger 配置文件详解

    Logback配置文件详解 Logback,Java 日志框架. Logback 如何加载配置的 logback 首先会查找 logback.groovy 文件 当没有找到,继续试着查找 logbac ...

  3. POJ2431_Expedition_KEY

    题目传送门 由题目可得,在一条路上有N个加油站,在距离终点a[i](细节)的位置上,你需要通过长度为L的路,油箱的容量是无限的,但是初始只有P点油,经过每个加油站时可以选择加b[i]的油,问最少加油几 ...

  4. HTML5 离线应用程序

    离线Web应用:当客户端本地与Web应用程序的服务器没有建立连接时,也能正常在客户端本地使用该Web应用. Web应用程序的本地缓存与浏览器的网页缓存的区别 1. 本地缓存为整个Web应用程序服务,网 ...

  5. JS学习 函数的理解

    ECMAScript 的函数实际上是功能完整的对象. 函数的理解 用 Function 类直接创建函数,格式如下.可理解为Function构造器. var function_name = new Fu ...

  6. SpringBoot学习:整合shiro(rememberMe记住我功能)

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 首先在shiro配置类中注入rememberMe管理器 /** * cookie对象; ...

  7. 转:asp.net mvc ef 性能监控调试工具 MiniProfiler

    MiniProfiler官网:http://miniprofiler.com/ MiniProfiler的一个特别有用的功能是它与数据库框架的集成.除了.NET原生的 DbConnection类,Mi ...

  8. 使用materialization

    explain select `countries`.`id` AS `id`,`countries`.`sortname` AS `sortname`,`countries`.`name` AS ` ...

  9. generator-ivweb 基于react-redux的多页脚手架

    背景 每个公司甚至每个项目组,在开发新项目的时候都会有一些自己特色的东西,比如公共组件,ajax请求拦截处理,内部积累的一些业务逻辑等等,如果没有自己的脚手架,那么拷贝代码成为常态,每个项目的结构,甚 ...

  10. 「日常训练」Battle Over Cities - Hard Version(PAT-TOP-1001)

    题意与分析 题意真的很简单,实在不想讲了,简单说下做法吧. 枚举删除每个点,然后求最小生成树,如果这个路已经存在那么边权就是0,否则按照原来的处理,之后求花费,然后判整个图是否联通(并查集有几个roo ...