1850 -- 【POJ1474】监控摄像头
Description
一个著名的仓库管理公司SERKOI 请你为其安装一套闭路监视系统,由于SERKOI 财力有限,每个房间只能安装一台摄像机,不过其镜头可以向任何方向转换。 请你写一个程序,对于给定的房间示意图,判断是否有可能在这个房间中的某一位置安置一台摄像机,使其能监视到房间的每一个角落。
Input
输入文件有多组数据。每一组的第一行是一个整数n(4<=n<=100),表示房间的示意图是一个n边形。接下来n行,按照顺时针给出这n个点的坐标。最后一组的第一行是0,表示结束。
Output
如果能找出安放摄像机的点则输出
Floor #1
Surveillance is possible.
否则输出:
Floor #1
Surveillance is impossible.
#后边的数字表示房间编号,按输入数据由小到大编号,第一个房间编号为1。每一组数据完后输出一个空行。
Sample Input
4
0 0
0 1
1 1
1 0
8
0 0
0 2
1 2
1 1
2 1
2 2
3 2
3 0
0
Sample Output
Floor #1
Surveillance is possible.
Floor #2
Description
一个著名的仓库管理公司SERKOI 请你为其安装一套闭路监视系统,由于SERKOI 财力有限,每个房间只能安装一台摄像机,不过其镜头可以向任何方向转换。 请你写一个程序,对于给定的房间示意图,判断是否有可能在这个房间中的某一位置安置一台摄像机,使其能监视到房间的每一个角落。
Input
输入文件有多组数据。每一组的第一行是一个整数n(4<=n<=100),表示房间的示意图是一个n边形。接下来n行,按照顺时针给出这n个点的坐标。最后一组的第一行是0,表示结束。
Output
如果能找出安放摄像机的点则输出
Floor #1
Surveillance is possible.
否则输出:
Floor #1
Surveillance is impossible.
#后边的数字表示房间编号,按输入数据由小到大编号,第一个房间编号为1。每一组数据完后输出一个空行。
Sample Input
4
0 0
0 1
1 1
1 0
8
0 0
0 2
1 2
1 1
2 1
2 2
3 2
3 0
0
Sample Output
Floor #1
Surveillance is possible.
Floor #2
Surveillance is impossible.
用给出的多边形来切一个极大的矩形,若是有剩下的块/点,说明可以监控到。
为什么呢?
我们说,要能观测到一条边,这个点一定在这条边的上方,比如:
中间的黄黄的阴影部分是合法的,其他的:
Block1----在E2下方,无法观测全部
Block2----在E1下方,无法观测全部
其实就是,当点连接边两点的两条边叉积之积>0,这个点在这条边的上方,
•
能观察到所有边的点一定能够观察到整个多边形区域。
其实再看,这个合法的块/点,就是拿这个多边形割这个平面得到的交。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct point
{
double x,y;
}p[300005];
int n,m;
void pre()
{
memset(p,0,sizeof(p));
}
double cross(point a,point b,point c)
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
point getnew(point a,point b,point c,point d)
{
double l1=abs(cross(c,b,a));
double l2=abs(cross(d,b,a));
point ans;
ans.x=(c.x*l2+d.x*l1)/(l1+l2);
ans.y=(c.y*l2+d.y*l1)/(l1+l2);
return ans;
}
void Cut(point last,point current)
{
point store[35];
int cnt=0;
p[n+1]=p[1];
for(int i=2;i<=n+1;i++)
{
double l=cross(p[i-1],current,last);
double r=cross(p[i],current,last);
//这里是顺时针给出的数据
if(l>=0)
{
store[++cnt]=p[i-1];
if(r<0)store[++cnt]=getnew(last,current,p[i],p[i-1]);
}
else if(r>0)store[++cnt]=getnew(last,current,p[i],p[i-1]);
}
for(int i=1;i<=cnt;i++)p[i]=store[i];
n=cnt;
}
int main(){
int test_case=0;
while(1)
{
scanf("%d",&m);
if(m==0)break;
n=4;
point last,current,first;
pre();
p[1]={-1e8,-1e8};
p[2]={-1e8,1e8};
p[3]={1e8,1e8};
p[4]={1e8,-1e8};
//极大矩形
scanf("%lf%lf",&last.x,&last.y);
first=last;
for(int i=2;i<=m;i++)
{
scanf("%lf%lf",¤t.x,¤t.y);
Cut(last,current);
last=current;
}
Cut(last,first);
test_case++;
printf("Floor #%d\n",test_case);
if(n>0)printf("Surveillance is possible.\n\n");
else printf("Surveillance is impossible.\n\n");
}
return 0;
}