zoukankan      html  css  js  c++  java
  • BNU校赛总决赛J 小白兔小灰兔 相交计算几何模板

    J 小白兔小灰兔

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    Special Judge, 64bit IO Format: %lld

    题目描述

    老山羊伯伯在地里收白菜,小白兔和小灰兔看见了就一起来帮忙。

    他们干了半天,终于干完了。

    羊伯伯:小灰兔,这车白菜送给你!

    小灰兔:谢谢羊伯伯!

    羊伯伯:小白兔,我也送你一车白菜!

    小白兔:我不要白菜!给我一包白菜种子吧!

    羊伯伯:好!给你~

    小白兔:谢谢羊伯伯~

    小灰兔把白菜拉到家里之后,就跟大家梦想中的生活一样,躺着啥都不干,吃吃吃,吃了玩~(好想一辈子都这样啊~小灰兔心想。)

    小白兔把种子拿回去,打算开始勤劳地种白菜。然而他发现不是所有土地都能用来种白菜,只有被阳光照到的地方可以种白菜。

    小白兔生活的星球可以看作二维平面中的一个简单多边形,太阳可以看作一个点。小白兔想知道,这个星球上一共有长度多少的土地可以用来种白菜。

    输入描述:

    第一行是一个正整数T(≤ 20),表示测试数据组数,

    对于每组测试数据,

    第一行是一个整数n(3≤ n≤ 10),表示简单多边形的顶点数,

    接下来n行,每行是两个整数xi,yi(-10≤ xi,yi≤10),按照逆时针绕向给出简单多边形的n个顶点的坐标,

    最后一行是两个整数x,y(-10≤ x,y≤10),表示太阳的坐标,保证太阳在多边形外且不在多边形任意一条边所在直线上。

    输出描述:

    对于每组测试数据,输出一行,包含一个实数,表示可以用来种白菜的土地的总长度,要求相对误差不超过

    也就是说,令输出结果为a,标准答案为b,若满足,则输出结果会被认为是正确答案。

    示例1

    输入

    2
    4
    0 0
    2 0
    2 2
    0 2
    4 1
    4
    0 0
    2 0
    2 2
    0 2
    4 4

    输出

    2.000000000000
    4.000000000000

      1 #include<bits/stdc++.h>
      2 #define clr(x) memset(x,0,sizeof(x))
      3 #define clr_1(x) memset(x,-1,sizeof(x))
      4 #define mod 1000000007
      5 #define INF 0x3f3f3f3f
      6 #define LL long long
      7 #define pb push_back
      8 #define pbk pop_back
      9 #define ls(i) (i<<1)
     10 #define rs(i) (i<<1|1)
     11 #define mp make_pair
     12 using namespace std;
     13 typedef double db;
     14 const int N=5e5+10;
     15 const db eps=1e-9;
     16 int equzero(db t)//带精度大小判断
     17 {
     18     if(t>eps) return 1;
     19     if(t<-eps) return -1;
     20     return 0;
     21 }
     22 struct Point
     23 {
     24     db x,y;
     25     Point(){}
     26     Point(db _x,db _y):x(_x),y(_y) {}
     27     Point operator +(const Point &b) const //+
     28     {
     29         return Point(x+b.x,y+b.y);
     30     }
     31     Point operator -(const Point &b) const//-
     32     {
     33         return Point(x-b.x,y-b.y);
     34     }
     35     Point operator *(const db &b) const// 放大
     36     {
     37         return Point(x*b,y*b);
     38     }
     39     Point operator /(const db &b) const//缩小
     40     {
     41         return Point (x/b,y/b);
     42     }
     43     db dot(const Point &b) const//点积
     44     {
     45         return x*b.x+y*b.y;
     46     }
     47     db det(const Point &b) const//叉积
     48     {
     49         return x*b.y-b.x*y;
     50     }
     51     bool operator ==(const Point &b) const
     52     {
     53         return  equzero(x-b.x)==0 && equzero(y-b.y)==0;
     54     }
     55     bool operator !=(const Point &b) const
     56     {
     57         return !(Point(x,y)==b);
     58     }
     59     db mo() //
     60     {
     61         return sqrt(x*x+y*y);
     62     }
     63 }pt[N],u,v,mid;
     64 struct Line
     65 {
     66     Point a,b;
     67     Line (){}
     68     Line (Point _a,Point _b):a(_a),b(_b) {};
     69     bool quickrej(const Line &t) const//快速排斥判断
     70     {
     71         return equzero(min(a.x,b.x)-max(t.a.x,t.b.x))<=0 && equzero(min(t.a.x,t.b.x)-max(a.x,b.x))<=0 && equzero(min(a.y,b.y)-max(t.a.y,t.b.y))<=0 && equzero(min(t.a.y,t.b.y)-max(a.y,b.y))<=0;
     72     }
     73     db len() const
     74     {
     75         return (b-a).mo();
     76     }
     77     bool stra(const Line &t) const //跨立判断
     78     {
     79         return equzero((a-t.a).det(t.b-t.a)*(b-t.a).det(t.b-t.a))<0 && equzero((t.a-a).det(b-a)*(t.b-a).det(b-a))<0 ;
     80     }
     81     bool gfxj(const Line &t) const //规范相交
     82     {
     83         return quickrej(t) && stra(t);
     84     }
     85     bool on(const Point &t) const //点在线段上
     86     {
     87         Line p=Line(a,b);
     88         if(p.a.x>p.b.x)
     89             swap(p.a,p.b);
     90         if(equzero(t.x-p.a.x)<0 || equzero(t.x-p.b.x)>0)
     91             return false;
     92         if(equzero((p.a-t).det(p.b-t))==0)
     93             return true;
     94         else
     95             return false;
     96     }
     97     bool kddxj(const Line &t) const //可多点相交
     98     {
     99         return quickrej(t) && (stra(t) || on(t.a) || on(t.b) || t.on(a) || t.on(b));
    100     }
    101     bool para(const Line &t) const // 平行或在一条直线上
    102     {
    103         return equzero((a.y-b.y)*(t.a.x-t.b.x)-(t.a.y-t.b.y)*(a.x-b.x))==0 ;
    104     }
    105     db operator & (const Line &t) const //返回切点占直线比例,距a比例
    106     {
    107         if(equzero((a-b).det(t.a-t.b))==0)return -INF;
    108         db tk=((a-t.a).det(t.a-t.b))/((a-b).det(t.a-t.b));
    109         return equzero(tk)>=0 && equzero(tk-1)<=0 ? tk : -INF;
    110     }
    111 }le[N],lu,lv;
    112 int n,m,T;
    113 vector<db> cp;
    114 db ans,ins,rate;
    115 bool flag;
    116 int main()
    117 {
    118     scanf("%d",&T);
    119     while(T--)
    120     {
    121         scanf("%d",&n);
    122         for(int i=0;i<=n;i++)
    123             scanf("%lf%lf",&pt[i].x,&pt[i].y);
    124         for(int i=0;i<n;i++)
    125             le[i]=Line(pt[i],pt[(i+1)%n]);
    126         ans=0;
    127         for(int i=0;i<n;i++)
    128         {
    129             cp.clear();
    130             for(int j=0;j<n;j++)
    131             {
    132                 ins=le[i]&Line(pt[n],pt[j]);
    133                 if(ins>=-1) cp.pb(ins);
    134             }
    135             sort(cp.begin(),cp.end());
    136             rate=0;
    137             for(int j=0;j<cp.size()-1;j++)
    138             {
    139                 lu=Line(pt[n],le[i].a+(le[i].b-le[i].a)*((cp[j]+cp[j+1])/2));
    140                 flag=0;
    141                 for(int k=0;k<n;k++)
    142                 {
    143                     if(lu.gfxj(le[k]))
    144                     {
    145                         flag=1;
    146                         break;
    147                     }
    148                 }
    149                 if(!flag)
    150                 {
    151                     rate+=cp[j+1]-cp[j];
    152                 }
    153             }
    154             ans+=rate*le[i].len();
    155         }
    156         printf("%.12f
    ",ans);
    157     }
    158     return 0;
    159 }
    View Code
  • 相关阅读:
    struts2文件上传报错
    简述算法和程序的区别并举例说明
    JAVA中TreeMap集合筛选字母及每一个字符出现的次数
    Myeclipse2014破解步骤
    修改ubuntu的终端提示符
    gcc 引用math.h头文件,编译出现undefined reference to `pow‘等错误时,需要加参数lm.
    几篇文章
    gdb调试gcc出现:Missing separate debuginfos, use: debuginfoinstall glibcx.i686
    【达内C++学习培训学习笔记系列】C语言之三循环语句和数组
    code::block之spell checker配置
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9004551.html
Copyright © 2011-2022 走看看