BZOJ3564 [SHOI2014]信号增幅仪

先把椭圆长轴转到x轴上,然后把x轴按照比例缩回去,于是就变成了最小圆覆盖问题,上板子。。。就行

  1 /**************************************************************
  2     Problem: 3564
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:256 ms
  7     Memory:2380 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cmath>
 12  
 13 using namespace std;
 14 typedef double lf;
 15 const int N = 5e4 + 5;
 16 const lf pi = acos(-1.0);
 17 const lf eps = 1e-7;
 18  
 19 inline int read();
 20  
 21 template <class T> T sqr(T x) {
 22     return x * x;
 23 }
 24  
 25 struct point {
 26     lf x, y;
 27     point() {}
 28     point(lf _x, lf _y) : x(_x), y(_y) {}
 29      
 30     inline void get() {
 31         x = read(), y = read();
 32     }
 33     inline void rev(lf a) {
 34         static lf tx, ty;
 35         tx = x * cos(a) - y * sin(a), ty = x * sin(a) + y * cos(a);
 36         x = tx, y = ty;
 37     }
 38      
 39     inline point operator + (const point &p) const {
 40         return point(x + p.x, y + p.y);
 41     }
 42     inline point operator - (const point &p) const {
 43         return point(x - p.x, y - p.y);
 44     }
 45     inline point operator / (lf t) const {
 46         return point(x / t, y / t);
 47     }
 48     inline lf operator * (const point &p) const {
 49         return x * p.y - y * p.x;
 50     }
 51      
 52     friend inline lf dis2(const point &p) {
 53         return sqr((lf) p.x) + sqr((lf) p.y);
 54     }
 55     friend inline point work(const point &a, const point &b, const point &c) {
 56         static point p, q, res;
 57         static lf d, ab, bc, ac;
 58         p = b - a, q = c - a, d = p * q * 2;
 59         if (fabs(d) < eps) {
 60             ab = dis2(b - a), bc = dis2(c - b), ac = dis2(c - a);
 61             if (ab - bc >= eps && ab - ac >= eps) return (a + b) / 2;
 62             if (bc - ab >= eps && bc - ac >= eps) return (b + c) / 2;
 63             return (a + c) / 2;
 64         }
 65         return point(dis2(p) * q.y - dis2(q) * p.y, dis2(q) * p.x - dis2(p) * q.x) / d + a;
 66     }
 67 } p[N], c[N];
 68  
 69 int n, cnt;
 70 lf alpha, P;
 71  
 72 inline lf min_cover() {
 73     static int i, j, k;
 74     static lf rad2;
 75     rad2 = cnt = 0;
 76     for (i = 1; i <= n; ++i) if (dis2(p[i] - c[cnt]) > rad2) {
 77         c[cnt] = p[i], rad2 = 0.0;
 78         for (j = 1; j < i; ++j) if (dis2(p[j] - c[cnt]) > rad2) {
 79             c[cnt] = (p[i] + p[j]) / 2.0, rad2 = dis2(p[i] - c[cnt]);
 80             for (k = 1; k < j; ++k) if (dis2(p[k] - c[cnt]) > rad2)
 81                 c[cnt] = work(p[i], p[j], p[k]), rad2 = dis2(p[i] - c[cnt]);
 82         }
 83     }
 84     return sqrt(rad2);
 85 }
 86   
 87  
 88 int main() {
 89     int i;
 90     n = read();
 91     for (i = 1; i <= n; ++i) p[i].get();
 92     alpha = (lf) read() / 180.0 * pi, P = read();
 93     for (i = 1; i <= n; ++i)
 94         p[i].rev(-alpha), p[i].x /= P;
 95     printf("%.3lf
", min_cover());
 96     return 0;
 97 }
 98  
 99 inline int read() {
100     static int x, sgn;
101     static char ch;
102     x = 0, sgn = 1, ch = getchar();
103     while (ch < '0' || '9' < ch) {
104         if (ch == '-') sgn = -1;
105         ch = getchar();
106     }
107     while ('0' <= ch && ch <= '9') {
108         x = x * 10 + ch - '0';
109         ch = getchar();
110     }
111     return sgn * x;
112 }
View Code

(p.s. rank.1液!转圈~转圈~)

By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4464340.html