poj 1474 半平面交求多边形的核

【题意】

是否能在房间中找到一个位置来安装摄像头,使摄像头能监控到房间的每个角落。在平面图上,房间的墙只有横和竖的,没有斜的。

【题解】

判断多边形是否存在核。用半平面交判断。

【代码】

#include <iostream>
#include <cmath>
#define eps 1e-8
#define oo 1e5
using namespace std;
const int maxn=105;

struct point
{
       double x,y;
}p[maxn],tp[maxn];
int n,nn;

int sig(double x)
{
    if (x<-eps) return -1;
    if (x>eps) return 1;
    return 0;
}

void getline(const point& p1,const point& p2,double & a,double & b,double & c)
{
     a=p2.y-p1.y;
     b=p1.x-p2.x;
     c=p2.x*p1.y-p2.y*p1.x;
}

point intersection(point u1,point u2,point v1,point v2)
{
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
    /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}

void cut(int& n,point* p,point l1,point l2)
{
     double a,b,c;
     point pp[maxn];
     int m=0,i;
     getline(l1,l2,a,b,c);
     for (i=0;i<n;i++)
         if (sig(a*p[i].x+b*p[i].y+c)>=0)
            pp[m++]=p[i];
         else
         {
             int t=(i-1+n)%n;
             if (sig(a*p[t].x+b*p[t].y+c)>0) pp[m++]=intersection(p[t],p[i],l1,l2);
             t=(i+1)%n;
             if (sig(a*p[t].x+b*p[t].y+c)>0) pp[m++]=intersection(p[t],p[i],l1,l2);
         }
     for (i=0;i<m;i++)
         p[i]=pp[i];
     n=m;
}

int main()
{
    freopen("pin.txt","r",stdin);
    freopen("pou.txt","w",stdout);
    int i,cc=0;
    while (1)
    {
          cin >> n;
          if (n==0) break;
          for (i=0;i<n;i++)
              cin >> p[i].x >> p[i].y;
          nn=4;
          tp[0].x=-oo;tp[0].y=oo;
          tp[1].x=oo;tp[1].y=oo;
          tp[2].x=oo;tp[2].y=-oo;
          tp[3].x=-oo;tp[3].y=-oo;
          for (i=0;i<n;i++)
              cut(nn,tp,p[i],p[(i+1)%n]);
          if (cc) cout << endl;
          cout << "Floor #" << ++cc << endl;
          if (nn<=0) cout << "Surveillance is impossible.\n";
          else cout << "Surveillance is possible.\n";
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值