监视摄像机

监视摄像机

时间限制: 1 Sec 内存限制: 32 MB

题目描述
一个著名的仓库管理公司*ERKOI请你的公司为其安装一套闭路监视系统。
由于 SERKOI财力有限,每个房间只能安装一台摄像机作监视用,不过它的镜头可以向任意方向旋转。
房间用一个封闭的多边形表示,一条边表示一面墙。

输入
输入文件包含一个或多个房间示意图的描述信息。
每个描述信息的第一行是一一个正整数n(4<=n<=100),表示该房间的示意图为一个n边形。
以下n行每行包括用空格符隔开的两个整数x,y,按顺时针方向依次为这个n边形的n个顶点在直角
坐标系中的的横纵坐标,x,y,的范围在:-1000至1000之间。若n等于0则表示输入文件结束。

输出
对于每个房间,首先输出一行该房间的编号信息“Room #k:”,k按照输入次序从1开始计数。
紧接着一行是判断结果,如果摄像机在房间中某处安置能满足条件,输出: “Surveillance is possible.”。
否则输出“Surveillance is impossible.” 每两个房间的输出结果之间用一个空行隔开

样例输入
4
0 0
0 1
1 1
1 0
8
0 0
3 0
4 3
2 2
3 4
4 4
4 5
0 5
0

样例输出
Room #1:
Surveillance is possible.
//注意:此处有换行
Room #2:
Surveillance is impossible.

来源
ctsc1998

题解

多年以前的ctsc题,判断能不能求半平面角即可。
另外,这题好像也可以不用半平面角搞。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define N 110
#define eps 1e-9
using namespace std;
int T,n;
struct point{
  double x,y;
  point operator+(const point &p)
  const{return (point){x+p.x,y+p.y};}
  point operator-(const point &p)
  const{return (point){x-p.x,y-p.y};}
  point operator*(const double &num)
  const{return (point){x*num,y*num};}
  double operator^(const point &p)
  const{return x*p.y-y*p.x;}
}t[N];
struct node{
  point x,y;double ang;
  bool operator<(const node &p)
  const{return ang>p.ang||(ang==p.ang&&(y^(p.x-x))>0);}
}s[N],q[N];
double get_ang(point p){return atan2(p.y,p.x);}
bool pd(node p,point q){return (p.y^(q-p.x))<eps;}
point get_jd(node p,node q)
{
  point v=p.x-q.x;
  double t=(q.y^v)/(p.y^q.y);
  point res=p.x+p.y*t;
  return p.x+p.y*t;
}

bool solve()
{
  sort(s+1,s+n+1);int tot=0;
  for(int i=1;i<=n;i++)
    if(s[i].ang!=s[i-1].ang)s[++tot]=s[i];
  int l=1,r=2;q[1]=s[1];q[2]=s[2];n=tot;
  for(int i=3;i<=n;i++)
  {
    while(l<r&&!pd(s[i],get_jd(q[r],q[r-1])))r--;
    while(l<r&&!pd(s[i],get_jd(q[l],q[l+1])))l++;
    if(l==r&&(s[i].y^q[r].y)<0)return false;
    q[++r]=s[i];
  }
  return true;
}

int main()
{
  while(1)
  {
    scanf("%d",&n);
    if(!n)break;
    for(int i=1;i<=n;i++)
      scanf("%lf%lf",&t[i].x,&t[i].y);t[n+1]=t[1];
    for(int i=1;i<=n;i++)
      s[i]=(node){t[i],t[i+1]-t[i],get_ang(t[i+1]-t[i])};
    printf("Room #%d:\n",++T);
    if(solve())printf("Surveillance is possible.\n");
    else printf("Surveillance is impossible.\n");
    printf("\n");
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值