poj1474 Video Surveillance
题意:求多边形的内核,即:在多边形内部找到某个点,使得从这个点能不受阻碍地看到多边形的所有位置.
只要能看到所有的边,就能看到所有的位置.那么如果我们能够在多边形的内部的点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的更多相关文章
- POJ1474 Video Surveillance(半平面交)
求多边形核的存在性,过了这题但是过不了另一题的,不知道是模板的问题还是什么,但是这个模板还是可以过绝大部分的题的... #pragma warning(disable:4996) #include & ...
- POJ1474:Video Surveillance(求多边形的核)(占位)
A friend of yours has taken the job of security officer at the Star-Buy Company, a famous depart- me ...
- poj 1474 Video Surveillance - 求多边形有没有核
/* poj 1474 Video Surveillance - 求多边形有没有核 */ #include <stdio.h> #include<math.h> const d ...
- poj 1474 Video Surveillance (半平面交)
链接:http://poj.org/problem?id=1474 Video Surveillance Time Limit: 1000MS Memory Limit: 10000K Total ...
- POJ1474:Video Surveillance——题解
http://poj.org/problem?id=1474 题目大意:给按照顺时针序的多边形顶点,问其是否有内核. —————————————————————————————— (和上道题目一模一样 ...
- POJ 1474 Video Surveillance(半平面交)
题目链接 2Y,模版抄错了一点. #include <cstdio> #include <cstring> #include <string> #include & ...
- Video Surveillance - POJ 1474(判断是否存在内核)
题目大意:询问是否在家里装一个监视器就可以监控所有的角落. 分析:赤裸裸的判断多边形内核题目. 代码如下: #include<iostream> #include<string.h& ...
- ●poj 1474 Video Surveillance
题链: http://poj.org/problem?id=1474 题解: 计算几何,半平面交 半平面交裸题,快要恶心死我啦... (了无数次之后,一怒之下把onleft改为onright,然后还加 ...
- POJ - 1474 :Video Surveillance (半平面交-求核)
pro:顺时针给定多边形,问是否可以放一个监控,可以监控到所有地方,即问是否存在多边形的核. 此题如果两点在同一边界上(且没有被隔段),也可以相互看到. sol:求多边形是否有核.先给直线按角度排序, ...
随机推荐
- ASP.NET数据库连接
启动Visual Studio,新建一个web工程 点开工程目录下web.config文件, 找到节点,新增数据库配置 aspx界面新建一个button和一个文本框用于测试数据库连接, 其中butto ...
- hdu5698瞬间移动(杨辉三角+快速幂+逆元)
瞬间移动 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- Qt-QML-自定义个自己的文本Text
好久都没有正经的更新自己的文章了,这段时间也辞职了,听了小爱的,准备买个碗,自己当老板,下面请欣赏效果图 这个界面布局就是自己是在想不到啥了,按照常规汽车导航的布局布局了一下,主要看内容哈,看看这个文 ...
- Linux命令应用大词典-第41章 MySQL数据库
41.1 mysqld_safe:MySQL服务器启动脚本 41.2 mysql_install_db:初始化MySQL数据目录 41.3 mysqlshow:显示MySQL数据库结构 41.4 my ...
- 韦大仙python--购物车
程序:购物车程序 需求: 启动程序后,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 可随时退出,退出时,打印已购买商品和余额 ...
- EditorGUI控件输入监听
EditorGUI控件输入监听 在做编辑器开放的过程中,有时候要对用户输入进行判断和限制,但EditorGUI控件却没有触发回调,而是提供了一种麻烦的办法--使用EditorGUI.BeginChan ...
- Unity制作人物头像小图标和小地图
人物头像的制作: 在场景中添加人物模型和环境模型 设置人物的layer为Player 在主摄像机的基础上,新建一个次摄像机并将摄像机镜头对准人物面部,调整至合适大小. 设置次摄像机 culling m ...
- linux 学习总结---- mysql 总结
用户的创建 ---->修改 ---->删除用户 create alter drop (数据定义语言 DDL) 授权: insert update delete grant *.* revo ...
- ajax 个人理解 学习笔记
W:Ajax Q:异步网络请求.无刷新请求数据. W:ajax的实现流程如下: Q: 创建XHR对象 调用open()方法,创建请求 调用send()方法,发送请求 捕获请求状态,判断请求结果 获取数 ...
- lintcode491 回文数
回文数 判断一个正整数是不是回文数. 回文数的定义是,将这个数反转之后,得到的数仍然是同一个数. 注意事项 给的数一定保证是32位正整数,但是反转之后的数就未必了. 您在真实的面试中是否遇到过这个题? ...