• [SHOI2014]信号增幅仪


    题目大意:
      平面直角坐标系中散落着n个点,一个椭圆的长半轴在对于x轴逆时针旋转α度的角度上,且长半轴是短半轴的k倍。
      问短半轴至少要多长才能覆盖所有的点?

    思路:
      首先把坐标顺时针旋转α度,然后把所有点的横坐标缩小k倍,就变成了最小圆覆盖问题。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     register bool neg=false;
     8     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
     9     register int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return neg?-x:x;
    12 }
    13 const int N=50000;
    14 const double eps=1e-4;
    15 struct Point {
    16     double x,y;
    17 };
    18 Point p[N];
    19 inline double sqr(const double &x) {
    20     return x*x;
    21 }
    22 inline double dis(const Point &a,const Point &b) {
    23     return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
    24 }
    25 inline Point mid(const Point &a,const Point &b) {
    26     return (Point){(a.x+b.x)/2,(a.y+b.y)/2};
    27 }
    28 inline Point out(const Point &a,const Point &b,const Point &c) {
    29     Point ret;
    30     ret.x=((sqr(a.x)+sqr(a.y))*b.y+(sqr(c.x)+sqr(c.y))*a.y+(sqr(b.x)+sqr(b.y))*c.y-(sqr(a.x)+sqr(a.y))*c.y-(sqr(c.x)+sqr(c.y))*b.y-(sqr(b.x)+sqr(b.y))*a.y)/(a.x*b.y+b.x*c.y+c.x*a.y-a.x*c.y-b.x*a.y-c.x*b.y)/2;
    31     ret.y=((sqr(a.x)+sqr(a.y))*c.x+(sqr(c.x)+sqr(c.y))*b.x+(sqr(b.x)+sqr(b.y))*a.x-(sqr(a.x)+sqr(a.y))*b.x-(sqr(c.x)+sqr(c.y))*a.x-(sqr(b.x)+sqr(b.y))*c.x)/(a.x*b.y+b.x*c.y+c.x*a.y-a.x*c.y-b.x*a.y-c.x*b.y)/2;
    32     return ret;
    33 }
    34 int main() {
    35     const int n=getint();
    36     for(register int i=0;i<n;i++) {
    37         p[i]=(Point){getint(),getint()};
    38     }
    39     const double alpha=getint()*M_PI/180,k=getint();
    40     for(register int i=0;i<n;i++) {
    41         const double x=p[i].x,y=p[i].y;
    42         p[i]=(Point){(x*cos(alpha)+y*sin(alpha))/k,y*cos(alpha)-x*sin(alpha)};
    43     }
    44     std::random_shuffle(&p[0],&p[n]);
    45     Point c=p[0];
    46     double r=0;
    47     for(register int i=1;i<n;i++) {
    48         if(dis(c,p[i])<r+eps) continue;
    49         c=p[i];
    50         r=0;
    51         for(register int j=0;j<i;j++) {
    52             if(dis(c,p[j])<r+eps) continue;
    53             c=mid(p[i],p[j]);
    54             r=dis(c,p[j]);
    55             for(register int k=0;k<j;k++) {
    56                 if(dis(c,p[k])<r+eps) continue;
    57                 c=out(p[i],p[j],p[k]);
    58                 r=dis(c,p[k]);
    59             }
    60         }
    61     }
    62     printf("%.3f
    ",r);
    63     return 0;
    64 }
  • 相关阅读:
    JAVA最简单常识
    BREW的资源文件概述及问题
    c语言 512
    c语言510 求矩阵的乘积
    c语言 511
    c语言57
    c语言 59
    c语言55 在应用对象式宏的数组中对数组元素进行倒序排列
    c语言 511
    c语言 510 求4行3列矩阵和3行4列矩阵的乘积。各构成元素的值从键盘输入。
  • 原文地址:https://www.cnblogs.com/skylee03/p/8085723.html
Copyright © 2020-2023  润新知