[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\n",r);
63     return 0;
64 }

 

posted @ 2017-12-22 14:07  skylee03  阅读(117)  评论(0编辑  收藏  举报