UVALive 7004-10.1训练赛

题意:

 就是给你一个点p,再给你几个多边形的顶点,让你去判断在多边形的边上,还是内部,还是外边

模板题

CODE


#include <iostream>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include <stdio.h>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x)
{
  if(fabs(x)<eps) return 0;
  if(x<0) return -1;
  else return 1;
}
struct Point
{
  double x,y;
  Point(){}
  Point(double _x,double _y)
  {
    x=_x;y=_y;
  }
  Point operator-(const Point &b)const
  {
    return Point(x-b.x,y-b.y);
  }
  double operator^(const Point &b) const
  {
    return x*b.y-y*b.x;
  }
  double operator*(const Point &b) const
  {
       return x*b.x+y*b.y;
  }
  void transXY(double B)
  {

    double tx=x,ty=y;
    x=tx*cos(B)-ty*sin(B);
    y=tx*sin(B)+ty*cos(B);
  }
};
struct Line
{
  Point s,e;
  Line(){}
  Line(Point _s,Point _e)
  {
    s=_s;e=_e;
  }
  pair<int,Point>operator &(const Line &b)const
  {
    Point res=s;
    if(sgn((s-e)^(b.s-b.e))==0)
    {
      if(sgn((s-b.e)^(b.s-b.e))==0)
        return make_pair(0,res);
      else return make_pair(1,res);
    }
    double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
    res.x+=(e.x-s.x)*t;
    res.y+=(e.y-s.y)*t;
    return make_pair(2,res);
  }
};
bool inter(Line l1,Line l2)
{
  return
  max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
  max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
  max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
  max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
  sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
  sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}
bool OnSeg(Point P,Line L)
{
  return
  sgn((L.s-P)^(L.e-P))==0&&
  sgn((P.x-L.s.x)*(P.x-L.e.x))<=0&&
  sgn((P.y-L.s.y)*(P.y-L.e.y))<=0;
}
int inPoly(Point p,Point poly[],int n)
{
  int cnt;
  Line ray,side;
  cnt=0;
  ray.s=p;
  ray.e.y=p.y;
  ray.e.x=-100000000000.0;
  for(int i=0;i<n;i++)
  {
    side.s = poly[i];
    side.e = poly[(i+1)%n];
    if(OnSeg(p,side)) return 0;
    if(sgn(side.s.y-side.e.y)==0)
        continue;
    if(OnSeg(side.s,ray))
    {
      if(sgn(side.s.y-side.e.y)>0) cnt++;
    }
    else if(OnSeg(side.e,ray))
    {
      if(sgn(side.e.y-side.s.y)>0) cnt++;
    }
    else if(inter(ray,side))
        cnt++;
  }
  if(cnt%2==1) return 1;
  else return -1;
}
Point a[100010];
Point t;
int b[100];
int main()
{
    int T;
    int n,x,y,m,s,e;

    scanf("%d",&T);

    while( T-- )
    {
        scanf("%d %lf %lf",&n,&t.x,&t.y);
        for( int i = 0; i < n; i++ )
        {
            scanf("%d",&m);
            for( int j = 0; j < m; j++ )
            {
                scanf("%lf %lf",&a[j].x,&a[j].y);
            }
            int flag = inPoly(t,a,m);
            if( flag == -1 )
            {
                b[i] = 2;///外面
            }
            else if( flag == 0 )
            {
                b[i] = 0;///边上
            }
            else
            {
                b[i] = 1;///里面
            }
        }

        for( int i = 0; i < n; i++ )
        {
             i == n-1 ? printf("%d\n",b[i]):printf("%d ",b[i]);
        }
    }

    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值