zoukankan      html  css  js  c++  java
  • UVALive4974 CERC2010B Beasts

    思想是半平面交+旋转卡壳,关于X轴取一次对称再求包围(0, -10^10)点的部分后再对称回来可以少写点针对性代码。左右的射线单独处理了。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 #include<iostream>
      6 #include<math.h>
      7 using namespace std;
      8 const int maxn = 211111;
      9 const double eps = 1e-9;
     10 typedef double PELEM;
     11 typedef long long LL;
     12 struct Point
     13 {
     14     PELEM x, y;
     15     Point()
     16     {
     17         x = y = 0;
     18     }
     19     Point(PELEM a, PELEM b)
     20     {
     21         x = a, y = b;
     22     }
     23     PELEM cross(const Point &b, const Point &c)const
     24     {
     25         return (b.x - x) * (c.y - y)
     26                - (c.x - x) * (b.y - y);
     27     }
     28     PELEM dot(const Point &p)const
     29     {
     30         return x * p.x + y * p.y;
     31     }
     32     Point operator-(const Point &p)const
     33     {
     34         return Point(x - p.x, y - p.y);
     35     }
     36     Point operator+(const Point &p)const
     37     {
     38         return Point(x + p.x, y + p.y);
     39     }
     40     Point operator-()const
     41     {
     42         return Point(-x, -y);
     43     }
     44 } p[2][maxn << 1];
     45 struct Line
     46 {
     47     LL a, b, c;
     48     bool operator<(const Line &l)const
     49     {
     50         if(a *l.b == b * l.a)
     51             return l.c * b < c * l.b;
     52         return a * l.b > b * l.a;
     53     }
     54     int CmXL(const Line &l)const
     55     {
     56         if(a * l.b < b * l.a) return 1;
     57         else if(a * l.b > b * l.a) return -1;
     58         return 0;
     59     }
     60     bool paral(const Line &l)const
     61     {
     62         return a * l.b == b * l.a;
     63     }
     64     bool high(const Point &p)const
     65     {
     66         return p.x * a + p.y * b - c > eps;
     67     }
     68     Point CrossP(const Line &l)const
     69     {
     70         return Point((double)(c * l.b - l.c * b) / (a * l.b - l.a * b),
     71                      (double)(c * l.a - l.c * a) / (b * l.a - l.b * a));
     72     }
     73 };
     74 void HPC(Line l[], int n, Point p[], Line nl[], int &pm, int &lm)
     75 {
     76     int i, tn;
     77     sort(l, l + n);
     78     pm = lm = 0;
     79     nl[lm ++] = l[0];
     80     for(i = 1; i < n; ++ i)
     81     {
     82         if(lm && nl[lm - 1].paral(l[i])) continue;
     83         while(pm && !l[i].high(p[pm - 1]))
     84             -- pm, -- lm;
     85         p[pm ++] = nl[lm - 1].CrossP(l[i]);
     86         nl[lm ++] = l[i];
     87     }
     88     if(pm == 0) p[pm ++] = Point(0, (double)nl[0].c / nl[0].b);
     89 }
     90 int n, pn1, pn2, ln1, ln2;
     91 Line l[maxn], l1[maxn], l2[maxn];
     92 Point p1[maxn], p2[maxn];
     93 Point CrossPoint(Point a, Point b, Point c, Point d)
     94 {
     95     double u = a.cross(b, c), v = b.cross(a, d);
     96     return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
     97 }
     98 double DisPtoP(Point a, Point b)
     99 {
    100     return (a - b).dot(a - b);
    101 }
    102 
    103 double DisPtoS(Point p, Point a, Point b, bool mk)
    104 {
    105     Point t = Point(p.x + a.y - b.y, p.y + b.x - a.x);
    106     if(mk && (t - a).dot(b - a) > eps || t.cross(a, p) * t.cross(b, p) < -eps)
    107         return DisPtoP(p, CrossPoint(t, p, a, b));
    108     return min(DisPtoP(p, a), DisPtoP(p, b));
    109 }
    110 double DisStoS(Point a, Point b, Point c, Point d)
    111 {
    112     double ans = 1e30;
    113     ans = min(ans, DisPtoS(a, c, d, 0));
    114     ans = min(ans, DisPtoS(b, c, d, 0));
    115     ans = min(ans, DisPtoS(c, a, b, 0));
    116     ans = min(ans, DisPtoS(d, a, b, 0));
    117     return ans;
    118 }
    119 int main()
    120 {
    121     int t, i, j, k;
    122     double ans;
    123     Point ts, te;
    124     for(scanf("%d", &t); t --; )
    125     {
    126         ans = 1e30;
    127         scanf("%d", &n);
    128         for(i = 0; i < n; ++ i)
    129         {
    130             scanf("%lld%lld%lld", &l[i].a, &l[i].b, &l[i].c), l[i].c = -l[i].c;
    131             if(l[i].b < 0) l[i].a = -l[i].a, l[i].b = -l[i].b, l[i].c = -l[i].c;
    132         }
    133         HPC(l, n, p1, l1, pn1, ln1);
    134         for(i = 0; i < n; ++ i)
    135             l[i].a = -l[i].a, l[i].c = -l[i].c;
    136         HPC(l, n, p2, l2, pn2, ln2);
    137         for(i = 0; i < ln2; ++ i)
    138             l2[i].a = -l2[i].a, l2[i].c = -l2[i].c;
    139         for(i = 0; i < pn2; ++ i)
    140             p2[i].y = -p2[i].y;
    141         for(i = 0, j = pn2 - 1; i + 1 < pn1 || j;)
    142         {
    143             if(j && (i == pn1 - 1 || l1[i + 1].CmXL(l2[j]) == 1))
    144                 ans = min(ans, DisPtoS(p1[i], p2[j - 1], p2[j], 0)), -- j;
    145             else if(i < pn1 - 1 && (!j || l1[i + 1].CmXL(l2[j]) == -1))
    146                 ans = min(ans, DisPtoS(p2[j], p1[i], p1[i + 1], 0)), ++ i;
    147             else
    148             {
    149                 ans = min(ans, DisStoS(p1[i], p1[i + 1], p2[j - 1], p2[j]));
    150                 ++ i, -- j;
    151             }
    152         }
    153         ts = Point(p2[0].x - 1, (l2[0].c - l2[0].a * (p2[0].x - 1)) / l2[0].b);
    154         te = Point(p2[pn2 - 1].x + 1, (l2[pn2].c - l2[pn2].a * (p2[pn2 - 1].x + 1)) / l2[pn2].b);
    155         for(i = 0; i < pn1; ++ i)
    156         {
    157             ans = min(ans, DisPtoS(p1[i], p2[0], ts, 1));
    158             ans = min(ans, DisPtoS(p1[i], p2[pn2 - 1], te, 1));
    159         }
    160         ts = Point(p1[0].x - 1, (l1[0].c - l1[0].a * (p1[0].x - 1)) / l1[0].b);
    161         te = Point(p1[pn1 - 1].x + 1, (l1[pn1].c - l1[pn1].a * (p1[pn1 - 1].x + 1)) / l1[pn1].b);
    162         for(i = 0; i < pn2; ++ i)
    163         {
    164             ans = min(ans, DisPtoS(p2[i], p1[0], ts, 1));
    165             ans = min(ans, DisPtoS(p2[i], p1[pn1 - 1], te, 1));
    166         }
    167         printf("%.6f\n", ans);
    168     }
    169     return 0;
    170 }
  • 相关阅读:
    Vue 插件写法
    js创建对象的多种方式及优缺点
    webpack原理与实战
    发布高性能迷你React框架anu
    Windows 同一时候开启核心显卡与独立显卡(不接显示器启动核芯显卡)
    基于QT和OpenCV的人脸检測识别系统(1)
    Cocos2d-x中背景音乐播放暂停与继续
    使用Xcode和Instruments调试解决iOS内存泄露
    Shell 命令行快捷键
    ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展(实例)
  • 原文地址:https://www.cnblogs.com/CSGrandeur/p/2659147.html
Copyright © 2011-2022 走看看