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\n", 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 }

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

时间: 2024-11-02 10:15:47

BZOJ3564 [SHOI2014]信号增幅仪的相关文章

[BZOJ 3564] [SHOI2014] 信号增幅仪 【最小圆覆盖】

题目链接:BZOJ - 3564 题目分析 求最小椭圆覆盖,题目给定了椭圆的长轴与 x 轴正方向的夹角,给定了椭圆长轴与短轴的比值. 那么先将所有点旋转一个角度,使椭圆长轴与 x 轴平行,再将所有点的 x 坐标除以长轴与短轴的比值,然后就直接做最小圆覆盖了. 随机增量法,一定别忘了 random_shuffle . 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstd

[SHTSC 2014] 信号增幅仪

最小覆盖圆算法.看着题解半蒙半抄的搞过去了… 主要参考以下http://blog.csdn.net/acdreamers/article/details/9406735http://blog.csdn.net/lthyxy/article/details/6661250http://blog.himdd.com/archives/2666 其中有一个求外心的过程是错的…害我调了好久…还把x和y搞反…可是就算是错的我居然过了80%的数据… 仍然几个疑问: (1)最小覆盖圆算法时间复杂度的证明 (2

bzoj-3564 信号增幅仪

题意: 给出平面上n个点和一个角度α,一个比值p: 求一个长轴与x轴夹角为α,长轴与短轴比值为p的椭圆, 包含了这n个点,且使半短轴最小: 题解: 本来只是上bz找找计算几何凸包啥的裸题刷刷,结果怎么碰上这么一个玄学的玩意... 况且这题还不用凸包: 看起来只是将圆拓展到了椭圆,但是直接按原模型乱搞似乎有些难度: 判断点和椭圆的关系需要一部转化: 两点间求椭圆,甚至三点间求椭圆都并不好搞,而且还有一个旋转的角度要考虑: 所以不能硬上,要转化模型,转化到熟悉的模型就可以搞了嘛: 将圆变成椭圆需要两

BZOJ 3564 SHOI 2014 信号增幅仪 坐标变换+最小圆覆盖

题目大意:给出平面上的一些点,现在让你用一个长轴与x轴成一定角度的,长轴:短轴已知的椭圆来覆盖所有的坐标,求最小的短轴长度. 思路:很明显,这个椭圆的形状和放置状态已经给出了,但是没有办法求最小拖圆覆盖啊.采用坐标变换,将椭圆变成圆.首先我们先让长轴与x轴平行,将平面上的所有点都旋转这个角度.之后只需要让所有点的x坐标除以长轴:短轴就可以了.剩下的就是最小圆覆盖了. 注:坐标旋转公式: x' = x * cos(a) - y * sin(a) y' = x * sin(a) + y * cos(

COGS2642 / Bzoj4590 [Shoi2015]自动刷题机

Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 906  Solved: 321 Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代码. B.心情不好,删掉了之前写的y行代码.(如果y大于当前代码长度则相当于全部删除.) 对于每

bzoj 4590

4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 860  Solved: 300[Submit][Status][Discuss] Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代码

BZOJ 4590: [Shoi2015]自动刷题机 二分答案

4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1056  Solved: 380[Submit][Status][Discuss] Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代

BZOJ4590 自动刷题机

SHOI2015 Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代码. B.心情不好,删掉了之前写的y行代码.(如果y大于当前代码长度则相当于全部删除.) 对于每个OJ所有题目,存在某个固定的长度n>0.一旦自动刷题机在某秒结束时积累了大于等于n行的代码,它就会 自动提交并

2015-4-18 经典训练1

T1:皇帝的烦恼 二分之后DP判断. 1 var v,a,b:array[0..30008] of longint; 2 n,ans,i,l,r,mid:longint; 3 function max(a,b:longint):longint; 4 begin 5 if a>b then exit(a); exit(b); 6 end; 7 function min(a,b:longint):longint; 8 begin 9 if a<b then exit(a); exit(b); 10