[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 }