zoukankan      html  css  js  c++  java
  • Poj 3384 Feng Shui

    地址:http://poj.org/problem?id=3384

    题目:

     

    Feng Shui
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 5551   Accepted: 1667   Special Judge

    Description

    Feng shui is the ancient Chinese practice of placement and arrangement of space to achieve harmony with the environment. George has recently got interested in it, and now wants to apply it to his home and bring harmony to it.

    There is a practice which says that bare floor is bad for living area since spiritual energy drains through it, so George purchased two similar round-shaped carpets (feng shui says that straight lines and sharp corners must be avoided). Unfortunately, he is unable to cover the floor entirely since the room has shape of a convex polygon. But he still wants to minimize the uncovered area by selecting the best placing for his carpets, and asks you to help.

    You need to place two carpets in the room so that the total area covered by both carpets is maximal possible. The carpets may overlap, but they may not be cut or folded (including cutting or folding along the floor border) — feng shui tells to avoid straight lines.

    Input

    The first line of the input file contains two integer numbers n and r — the number of corners in George’s room (3 ≤ n ≤ 100) and the radius of the carpets (1 ≤ r ≤ 1000, both carpets have the same radius). The following n lines contain two integers xi and yi each — coordinates of the i-th corner (−1000 ≤ xiyi ≤ 1000). Coordinates of all corners are different, and adjacent walls of the room are not collinear. The corners are listed in clockwise order.

    Output

    Write four numbers x1y1x2y2 to the output file, where (x1y1) and (x2y2) denote the spots where carpet centers should be placed. Coordinates must be precise up to 4 digits after the decimal point.

    If there are multiple optimal placements available, return any of them. The input data guarantees that at least one solution exists.

    Sample Input

    #1 5 2
    -2 0
    -5 3
    0 8
    7 3
    5 0
    #2 4 3
    0 0
    0 8
    10 8
    10 0

    Sample Output

    #1 -2 3 3 2.5
    #2 3 5 7 3

    Hint

    Source

    Northeastern Europe 2006, Northern Subregion

    思路:把边向内推r距离,然后求凸包,之后再求出凸包内距离最远的两个点即可。

      至于怎么内推,找出线段ab的方向向量(x,y),那么向量c(-y,x)即是ab的垂线,再将c单位化后乘以r,线段(a+c)(b+c)即是内推后的线段位置。

      不过这题spj好邪啊

    for(int i=n;i;i--)
                ln[n-i]=Line(pt[i],pt[i-1]);
    for(int i=0;i<n;i++)
                ln[i]=Line(pt[i+1],pt[i]);
    spj好邪啊,上面两种写法第一种ac,第二wa的不能自理。
    求半平面交,和线段顺序无关啊,只和线段方向有关啊。
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <algorithm>
      5 
      6 
      7 using namespace std;
      8 const double eps = 1e-10;
      9 //
     10 class Point
     11 {
     12 public:
     13     double x, y;
     14 
     15     Point(){}
     16     Point(double x, double y):x(x),y(y){}
     17 
     18     bool operator < (const Point &_se) const
     19     {
     20         return x<_se.x || (x==_se.x && y<_se.y);
     21     }
     22     /*******判断ta与tb的大小关系*******/
     23     static int sgn(double ta,double tb)
     24     {
     25         if(fabs(ta-tb)<eps)return 0;
     26         if(ta<tb)   return -1;
     27         return 1;
     28     }
     29     static double xmult(const Point &po, const Point &ps, const Point &pe)
     30     {
     31         return (ps.x - po.x) * (pe.y - po.y) - (pe.x - po.x) * (ps.y - po.y);
     32     }
     33     friend Point operator + (const Point &_st,const Point &_se)
     34     {
     35         return Point(_st.x + _se.x, _st.y + _se.y);
     36     }
     37     friend Point operator - (const Point &_st,const Point &_se)
     38     {
     39         return Point(_st.x - _se.x, _st.y - _se.y);
     40     }
     41     //点位置相同(double类型)
     42     bool operator == (const Point &_off) const
     43     {
     44         return  Point::sgn(x, _off.x) == 0 && Point::sgn(y, _off.y) == 0;
     45     }
     46     //点位置不同(double类型)
     47     bool operator != (const Point &_Off) const
     48     {
     49         return ((*this) == _Off) == false;
     50     }
     51     //两点间距离的平方
     52     static double dis2(const Point &_st,const Point &_se)
     53     {
     54         return (_st.x - _se.x) * (_st.x - _se.x) + (_st.y - _se.y) * (_st.y - _se.y);
     55     }
     56     //两点间距离
     57     static double dis(const Point &_st, const Point &_se)
     58     {
     59         return sqrt((_st.x - _se.x) * (_st.x - _se.x) + (_st.y - _se.y) * (_st.y - _se.y));
     60     }
     61 };
     62 //两点表示的向量
     63 class Line
     64 {
     65 public:
     66     Point s, e;//两点表示,起点[s],终点[e]
     67     double a, b, c;//一般式,ax+by+c=0
     68 
     69     Line(){}
     70     Line(const Point &s, const Point &e):s(s),e(e){}
     71     Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}
     72 
     73     //向量与点的叉乘,参数:点[_Off]
     74     //[点相对向量位置判断]
     75     double operator /(const Point &_Off) const
     76     {
     77         return (_Off.y - s.y) * (e.x - s.x) - (_Off.x - s.x) * (e.y - s.y);
     78     }
     79     //向量与向量的叉乘,参数:向量[_Off]
     80     friend double operator /(const Line &_st,const Line &_se)
     81     {
     82         return (_st.e.x - _st.s.x) * (_se.e.y - _se.s.y) - (_st.e.y - _st.s.y) * (_se.e.x - _se.s.x);
     83     }
     84     friend double operator *(const Line &_st,const Line &_se)
     85     {
     86         return (_st.e.x - _st.s.x) * (_se.e.x - _se.s.x) - (_st.e.y - _st.s.y) * (_se.e.y - _se.s.y);
     87     }
     88     //从两点表示转换为一般表示
     89     //a=y2-y1,b=x1-x2,c=x2*y1-x1*y2
     90     bool pton()
     91     {
     92         a = e.y - s.y;
     93         b = s.x - e.x;
     94         c = e.x * s.y - e.y * s.x;
     95         return true;
     96     }
     97 
     98     //-----------点和直线(向量)-----------
     99     //点在向量左边(右边的小于号改成大于号即可,在对应直线上则加上=号)
    100     //参数:点[_Off],向量[_Ori]
    101     friend bool operator<(const Point &_Off, const Line &_Ori)
    102     {
    103         return (_Ori.e.y - _Ori.s.y) * (_Off.x - _Ori.s.x)
    104             < (_Off.y - _Ori.s.y) * (_Ori.e.x - _Ori.s.x);
    105     }
    106 
    107     //点在直线上,参数:点[_Off]
    108     bool lhas(const Point &_Off) const
    109     {
    110         return Point::sgn((*this) / _Off, 0) == 0;
    111     }
    112     //点在线段上,参数:点[_Off]
    113     bool shas(const Point &_Off) const
    114     {
    115         return lhas(_Off)
    116             && Point::sgn(_Off.x - min(s.x, e.x), 0) > 0 && Point::sgn(_Off.x - max(s.x, e.x), 0) < 0
    117             && Point::sgn(_Off.y - min(s.y, e.y), 0) > 0 && Point::sgn(_Off.y - max(s.y, e.y), 0) < 0;
    118     }
    119 
    120     //点到直线/线段的距离
    121     //参数: 点[_Off], 是否是线段[isSegment](默认为直线)
    122     double dis(const Point &_Off, bool isSegment = false)
    123     {
    124         ///化为一般式
    125         pton();
    126 
    127         //到直线垂足的距离
    128         double td = (a * _Off.x + b * _Off.y + c) / sqrt(a * a + b * b);
    129 
    130         //如果是线段判断垂足
    131         if(isSegment)
    132         {
    133             double xp = (b * b * _Off.x - a * b * _Off.y - a * c) / ( a * a + b * b);
    134             double yp = (-a * b * _Off.x + a * a * _Off.y - b * c) / (a * a + b * b);
    135             double xb = max(s.x, e.x);
    136             double yb = max(s.y, e.y);
    137             double xs = s.x + e.x - xb;
    138             double ys = s.y + e.y - yb;
    139             if(xp > xb + eps || xp < xs - eps || yp > yb + eps || yp < ys - eps)
    140                 td = min(Point::dis(_Off,s), Point::dis(_Off,e));
    141         }
    142 
    143         return fabs(td);
    144     }
    145 
    146     //关于直线对称的点
    147     Point mirror(const Point &_Off) const
    148     {
    149         ///注意先转为一般式
    150         Point ret;
    151         double d = a * a + b * b;
    152         ret.x = (b * b * _Off.x - a * a * _Off.x - 2 * a * b * _Off.y - 2 * a * c) / d;
    153         ret.y = (a * a * _Off.y - b * b * _Off.y - 2 * a * b * _Off.x - 2 * b * c) / d;
    154         return ret;
    155     }
    156     //计算两点的中垂线
    157     static Line ppline(const Point &_a, const Point &_b)
    158     {
    159         Line ret;
    160         ret.s.x = (_a.x + _b.x) / 2;
    161         ret.s.y = (_a.y + _b.y) / 2;
    162         //一般式
    163         ret.a = _b.x - _a.x;
    164         ret.b = _b.y - _a.y;
    165         ret.c = (_a.y - _b.y) * ret.s.y + (_a.x - _b.x) * ret.s.x;
    166         //两点式
    167         if(std::fabs(ret.a) > eps)
    168         {
    169             ret.e.y = 0.0;
    170             ret.e.x = - ret.c / ret.a;
    171             if(ret.e == ret. s)
    172             {
    173                 ret.e.y = 1e10;
    174                 ret.e.x = - (ret.c - ret.b * ret.e.y) / ret.a;
    175             }
    176         }
    177         else
    178         {
    179             ret.e.x = 0.0;
    180             ret.e.y = - ret.c / ret.b;
    181             if(ret.e == ret. s)
    182             {
    183                 ret.e.x = 1e10;
    184                 ret.e.y = - (ret.c - ret.a * ret.e.x) / ret.b;
    185             }
    186         }
    187         return ret;
    188     }
    189 
    190     //------------直线和直线(向量)-------------
    191     //直线重合,参数:直线向量[_st],[_se]
    192     static bool equal(const Line &_st, const Line &_se)
    193     {
    194         return _st.lhas(_se.e) && _se.lhas(_se.s);
    195     }
    196     //直线平行,参数:直线向量[_st],[_se]
    197     static bool parallel(const Line &_st,const Line &_se)
    198     {
    199         return Point::sgn(_st / _se, 0) == 0;
    200     }
    201     //两直线(线段)交点,参数:直线向量[_st],[_se],交点
    202     //返回-1代表平行,0代表重合,1代表相交
    203     static bool crossLPt(const Line &_st,const Line &_se,Point &ret)
    204     {
    205         if(Line::parallel(_st,_se))
    206         {
    207             if(Line::equal(_st,_se)) return 0;
    208             return -1;
    209         }
    210         ret = _st.s;
    211         double t = (Line(_st.s,_se.s)/_se)/(_st/_se);
    212         ret.x += (_st.e.x - _st.s.x) * t;
    213         ret.y += (_st.e.y - _st.s.y) * t;
    214         return 1;
    215     }
    216     //------------线段和直线(向量)----------
    217     //线段和直线交
    218     //参数:直线[_st],线段[_se]
    219     friend bool crossSL(const Line &_st,const Line &_se)
    220     {
    221         return Point::sgn((_st / _se.s) * (_st / _se.e) ,0) <= 0;
    222     }
    223 
    224     //------------线段和线段(向量)----------
    225     //判断线段是否相交(注意添加eps),参数:线段[_st],线段[_se]
    226     static bool isCrossSS(const Line &_st,const Line &_se)
    227     {
    228         //1.快速排斥试验判断以两条线段为对角线的两个矩形是否相交
    229         //2.跨立试验(等于0时端点重合)
    230         return
    231             max(_st.s.x, _st.e.x) >= min(_se.s.x, _se.e.x) &&
    232             max(_se.s.x, _se.e.x) >= min(_st.s.x, _st.e.x) &&
    233             max(_st.s.y, _st.e.y) >= min(_se.s.y, _se.e.y) &&
    234             max(_se.s.y, _se.e.y) >= min(_st.s.y, _st.e.y) &&
    235             Point::sgn((_st / Line(_st.s, _se.s)) * (_st / Line(_st.s, _se.e)), 0) <= 0 &&
    236             Point::sgn((_se / Line(_se.s, _st.s)) * (_se / Line(_se.s, _st.e)), 0) <= 0;
    237     }
    238 };
    239 class Polygon
    240 {
    241 public:
    242     const static int maxpn = 100;
    243     Point pt[maxpn];//点(顺时针或逆时针)
    244     int n;//点的个数
    245 
    246     Point& operator[](int _p)
    247     {
    248         return pt[_p];
    249     }
    250 
    251     //求多边形面积,多边形内点必须顺时针或逆时针
    252     double area() const
    253     {
    254         double ans = 0.0;
    255         for(int i = 0; i < n; i ++)
    256         {
    257             int nt = (i + 1) % n;
    258             ans += pt[i].x * pt[nt].y - pt[nt].x * pt[i].y;
    259         }
    260         return fabs(ans / 2.0);
    261     }
    262     //求多边形重心,多边形内点必须顺时针或逆时针
    263     Point gravity() const
    264     {
    265         Point ans;
    266         ans.x = ans.y = 0.0;
    267         double area = 0.0;
    268         for(int i = 0; i < n; i ++)
    269         {
    270             int nt = (i + 1) % n;
    271             double tp = pt[i].x * pt[nt].y - pt[nt].x * pt[i].y;
    272             area += tp;
    273             ans.x += tp * (pt[i].x + pt[nt].x);
    274             ans.y += tp * (pt[i].y + pt[nt].y);
    275         }
    276         ans.x /= 3 * area;
    277         ans.y /= 3 * area;
    278         return ans;
    279     }
    280     //判断点在凸多边形内,参数:点[_Off]
    281     bool chas(const Point &_Off) const
    282     {
    283         double tp = 0, np;
    284         for(int i = 0; i < n; i ++)
    285         {
    286             np = Line(pt[i], pt[(i + 1) % n]) / _Off;
    287             if(tp * np < -eps)
    288                 return false;
    289             tp = (fabs(np) > eps)?np: tp;
    290         }
    291         return true;
    292     }
    293     //判断点是否在任意多边形内[射线法],O(n)
    294     bool ahas(const Point &_Off) const
    295     {
    296         int ret = 0;
    297         double infv = 1e-10;//坐标系最大范围
    298         Line l = Line(_Off, Point( -infv ,_Off.y));
    299         for(int i = 0; i < n; i ++)
    300         {
    301             Line ln = Line(pt[i], pt[(i + 1) % n]);
    302             if(fabs(ln.s.y - ln.e.y) > eps)
    303             {
    304                 Point tp = (ln.s.y > ln.e.y)? ln.s: ln.e;
    305                 if(fabs(tp.y - _Off.y) < eps && tp.x < _Off.x + eps)
    306                     ret ++;
    307             }
    308             else if(Line::isCrossSS(ln,l))
    309                 ret ++;
    310         }
    311         return (ret % 2 == 1);
    312     }
    313     //凸多边形被直线分割,参数:直线[_Off]
    314     Polygon split(Line _Off)
    315     {
    316         //注意确保多边形能被分割
    317         Polygon ret;
    318         Point spt[2];
    319         double tp = 0.0, np;
    320         bool flag = true;
    321         int i, pn = 0, spn = 0;
    322         for(i = 0; i < n; i ++)
    323         {
    324             if(flag)
    325                 pt[pn ++] = pt[i];
    326             else
    327                 ret.pt[ret.n ++] = pt[i];
    328             np = _Off / pt[(i + 1) % n];
    329             if(tp * np < -eps)
    330             {
    331                 flag = !flag;
    332                 Line::crossLPt(_Off,Line(pt[i], pt[(i + 1) % n]),spt[spn++]);
    333             }
    334             tp = (fabs(np) > eps)?np: tp;
    335         }
    336         ret.pt[ret.n ++] = spt[0];
    337         ret.pt[ret.n ++] = spt[1];
    338         n = pn;
    339         return ret;
    340     }
    341 
    342 
    343     /** 卷包裹法求点集凸包,_p为输入点集,_n为点的数量 **/
    344     void ConvexClosure(Point _p[],int _n)
    345     {
    346         sort(_p,_p+_n);
    347         n=0;
    348         for(int i=0;i<_n;i++)
    349         {
    350             while(n>1&&Point::sgn(Line(pt[n-2],pt[n-1])/Line(pt[n-2],_p[i]),0)<=0)
    351                 n--;
    352             pt[n++]=_p[i];
    353         }
    354         int _key=n;
    355         for(int i=_n-2;i>=0;i--)
    356         {
    357             while(n>_key&&Point::sgn(Line(pt[n-2],pt[n-1])/Line(pt[n-2],_p[i]),0)<=0)
    358                 n--;
    359             pt[n++]=_p[i];
    360         }
    361         if(n>1)   n--;//除去重复的点,该点已是凸包凸包起点
    362     }
    363 //    /****** 寻找凸包的graham 扫描法********************/
    364 //    /****** _p为输入的点集,_n为点的数量****************/
    365 //    /**使用时需把gmp函数放在类外,并且看情况修改pt[0]**/
    366 //    bool gcmp(const Point &ta,const Point &tb)/// 选取与最后一条确定边夹角最小的点,即余弦值最大者
    367 //    {
    368 //        double tmp=Line(pt[0],ta)/Line(pt[0],tb);
    369 //        if(Point::sgn(tmp,0)==0)
    370 //            return Point::dis(pt[0],ta)<Point::dis(pt[0],tb);
    371 //        else if(tmp>0)
    372 //            return 1;
    373 //        return 0;
    374 //    }
    375 //    void graham(Point _p[],int _n)
    376 //    {
    377 //        int cur=0;
    378 //        for(int i=1;i<_n;i++)
    379 //            if(Point::sgn(_p[cur].y,_p[i].y)>0 || (Point::sgn(_p[cur].y,_p[i].y)==0 && Point::sgn(_p[cur].x,_p[i].x)>0))
    380 //                cur=i;
    381 //        swap(_p[cur],_p[0]);
    382 //        n=0,pt[n++]=_p[0];
    383 //        if(_n==1)   return;
    384 //        sort(_p+1,_p+_n,Polygon::gcmp);
    385 //        pt[n++]=_p[1],pt[n++]=_p[2];
    386 //        for(int i=3;i<_n;i++)
    387 //        {
    388 //            while(Point::sgn(Line(pt[n-2],pt[n-1])/Line(pt[n-2],_p[i]),0)<0)
    389 //                n--;
    390 //            pt[n++]=_p[i];
    391 //        }
    392 //    }
    393     //凸包旋转卡壳(注意点必须顺时针或逆时针排列)
    394     //返回值凸包直径的平方(最远两点距离的平方)
    395     double rotating_calipers()
    396     {
    397         int i = 1;
    398         double ret = 0.0;
    399         pt[n] = pt[0];
    400         for(int j = 0; j < n; j ++)
    401         {
    402             while(fabs(Point::xmult(pt[i+1],pt[j], pt[j + 1])) > fabs(Point::xmult(pt[i],pt[j], pt[j + 1])) + eps)
    403                 i = (i + 1) % n;
    404             //pt[i]和pt[j],pt[i + 1]和pt[j + 1]可能是对踵点
    405             ret = (ret, max(Point::dis(pt[i],pt[j]), Point::dis(pt[i + 1],pt[j + 1])));
    406         }
    407         return ret;
    408     }
    409 
    410     //凸包旋转卡壳(注意点必须逆时针排列)
    411     //返回值两凸包的最短距离
    412     double rotating_calipers(Polygon &_Off)
    413     {
    414         int i = 0;
    415         double ret = 1e10;//inf
    416         pt[n] = pt[0];
    417         _Off.pt[_Off.n] = _Off.pt[0];
    418         //注意凸包必须逆时针排列且pt[0]是左下角点的位置
    419         while(_Off.pt[i + 1].y > _Off.pt[i].y)
    420             i = (i + 1) % _Off.n;
    421         for(int j = 0; j < n; j ++)
    422         {
    423             double tp;
    424             //逆时针时为 >,顺时针则相反
    425             while((tp = Point::xmult(_Off.pt[i + 1],pt[j], pt[j + 1]) - Point::xmult(_Off.pt[i], pt[j], pt[j + 1])) > eps)
    426                 i = (i + 1) % _Off.n;
    427             //(pt[i],pt[i+1])和(_Off.pt[j],_Off.pt[j + 1])可能是最近线段
    428             ret = min(ret, Line(pt[j], pt[j + 1]).dis(_Off.pt[i], true));
    429             ret = min(ret, Line(_Off.pt[i], _Off.pt[i + 1]).dis(pt[j + 1], true));
    430             if(tp > -eps)//如果不考虑TLE问题最好不要加这个判断
    431             {
    432                 ret = min(ret, Line(pt[j], pt[j + 1]).dis(_Off.pt[i + 1], true));
    433                 ret = min(ret, Line(_Off.pt[i], _Off.pt[i + 1]).dis(pt[j], true));
    434             }
    435         }
    436         return ret;
    437     }
    438 
    439     //-----------半平面交-------------
    440     //复杂度:O(nlog2(n))
    441     //#include <algorithm>
    442     //半平面计算极角函数[如果考虑效率可以用成员变量记录]
    443     static double hpc_pa(const Line &_Off)
    444     {
    445         return atan2(_Off.e.y - _Off.s.y, _Off.e.x - _Off.s.x);
    446     }
    447     //半平面交排序函数[优先顺序: 1.极角 2.前面的直线在后面的左边]
    448     static bool hpc_cmp(const Line &l, const Line &r)
    449     {
    450         double lp = hpc_pa(l), rp = hpc_pa(r);
    451         if(fabs(lp - rp) > eps)
    452             return lp < rp;
    453         return Point::xmult(r.s,l.s, r.e) < -eps;
    454     }
    455     static int judege(const Line &_lx,const Line &_ly,const Line &_lz)
    456     {
    457         Point tmp;
    458         Line::crossLPt(_lx,_ly,tmp);
    459         return Point::sgn(Point::xmult(_lz.s,tmp,_lz.e),0);
    460     }
    461     //获取半平面交的多边形(多边形的核)
    462     //参数:向量集合[l],向量数量[ln];(半平面方向在向量左边)
    463     //函数运行后如果n[即返回多边形的点数量]为0则不存在半平面交的多边形(不存在区域或区域面积无穷大)
    464     Polygon& halfPanelCross(Line _Off[], int ln)
    465     {
    466         Line dequeue[maxpn];//用于计算的双端队列
    467         int i, tn, bot, top;
    468         sort(_Off, _Off + ln, hpc_cmp);
    469         //平面在向量左边的筛选
    470         for(i = tn = 1; i < ln; i ++)
    471             if(fabs(hpc_pa(_Off[i]) - hpc_pa(_Off[i - 1])) > eps)
    472                 _Off[tn ++] = _Off[i];
    473         ln = tn, n = 0, bot = 0, top = 1;
    474         dequeue[0] = _Off[0];
    475         dequeue[1] = _Off[1];
    476         for(i = 2; i < ln; i ++)
    477         {
    478             while(bot < top &&  Polygon::judege(dequeue[top],dequeue[top-1],_Off[i]) > 0)
    479                 top --;
    480             while(bot < top &&  Polygon::judege(dequeue[bot],dequeue[bot+1],_Off[i]) > 0)
    481                 bot ++;
    482             dequeue[++ top] = _Off[i];
    483         }
    484         while(bot < top && Polygon::judege(dequeue[top],dequeue[top-1],dequeue[bot]) > 0)
    485             top --;
    486         while(bot < top && Polygon::judege(dequeue[bot],dequeue[bot+1],dequeue[top]) > 0)
    487             bot ++;
    488         //计算交点(注意不同直线形成的交点可能重合)
    489         if(top <= bot + 1)
    490             return (*this);
    491         for(i = bot; i < top; i ++)
    492             Line::crossLPt(dequeue[i],dequeue[i + 1],pt[n++]);
    493         if(bot < top + 1)
    494             Line::crossLPt(dequeue[bot],dequeue[top],pt[n++]);
    495         return (*this);
    496     }
    497 };
    498 
    499 Point pt[100];
    500 Line ln[100];
    501 Polygon py;
    502 int n;
    503 
    504 void ml(Line &lx,Line &ly,double t)
    505 {
    506     Point tmp=lx.e-lx.s,of;
    507     of=Point(-tmp.y,tmp.x);
    508     double dis=sqrt(of.x*of.x+of.y*of.y);
    509     of.x=of.x*t/dis,of.y=of.y*t/dis;
    510     ly.s=lx.s+of,ly.e=lx.e+of;
    511 }
    512 int main(void)
    513 {
    514     double r;
    515     while(~scanf("%d%lf",&n,&r))
    516     {
    517         Point ta,tb;
    518         double mx=-1;
    519         for(int i=0;i<n;i++)
    520             scanf("%lf%lf",&pt[i].x,&pt[i].y);
    521         pt[n]=pt[0];
    522         //for(int i=0;i<n;i++)
    523         //    ln[i]=Line(pt[i+1],pt[i]);
    524         for(int i=n;i;i--)
    525             ln[n-i]=Line(pt[i],pt[i-1]);
    526         for(int i=0;i<n;i++)
    527             ml(ln[i],ln[i],r);
    528         py.halfPanelCross(ln,n);
    529         for(int i=0;i<py.n;i++)
    530         for(int j=0;j<py.n;j++)
    531         if(Point::dis2(py.pt[i],py.pt[j])>mx)
    532             ta=py.pt[i],tb=py.pt[j],mx=Point::dis2(py.pt[i],py.pt[j]);
    533         printf("%.6f %.6f %.6f %.6f
    ",ta.x,ta.y,tb.x,tb.y);
    534     }
    535     return 0;
    536 }

     

  • 相关阅读:
    vim常用命令
    Leetcode686.Repeated String Match重复叠加字符串匹配
    Leetcode686.Repeated String Match重复叠加字符串匹配
    (转)Sql server中 如何用sql语句创建视图
    (转)Sql server中 如何用sql语句创建视图
    SQL Sever实验三 视图与数据更新
    SQL Sever实验三 视图与数据更新
    Leetcode653.Two Sum IV
    Leetcode653.Two Sum IV
    Leetcode661.Image Smoother图片平滑器
  • 原文地址:https://www.cnblogs.com/weeping/p/6376050.html
Copyright © 2011-2022 走看看