题目大意:
平面直角坐标系中散落着n个点,一个椭圆的长半轴在对于x轴逆时针旋转α度的角度上,且长半轴是短半轴的k倍。
问短半轴至少要多长才能覆盖所有的点?
思路:
首先把坐标顺时针旋转α度,然后把所有点的横坐标缩小k倍,就变成了最小圆覆盖问题。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return neg?-x:x;
}
const int N=;
const double eps=1e-;
struct Point {
double x,y;
};
Point p[N];
inline double sqr(const double &x) {
return x*x;
}
inline double dis(const Point &a,const Point &b) {
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
inline Point mid(const Point &a,const Point &b) {
return (Point){(a.x+b.x)/,(a.y+b.y)/};
}
inline Point out(const Point &a,const Point &b,const Point &c) {
Point ret;
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)/;
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)/;
return ret;
}
int main() {
const int n=getint();
for(register int i=;i<n;i++) {
p[i]=(Point){getint(),getint()};
}
const double alpha=getint()*M_PI/,k=getint();
for(register int i=;i<n;i++) {
const double x=p[i].x,y=p[i].y;
p[i]=(Point){(x*cos(alpha)+y*sin(alpha))/k,y*cos(alpha)-x*sin(alpha)};
}
std::random_shuffle(&p[],&p[n]);
Point c=p[];
double r=;
for(register int i=;i<n;i++) {
if(dis(c,p[i])<r+eps) continue;
c=p[i];
r=;
for(register int j=;j<i;j++) {
if(dis(c,p[j])<r+eps) continue;
c=mid(p[i],p[j]);
r=dis(c,p[j]);
for(register int k=;k<j;k++) {
if(dis(c,p[k])<r+eps) continue;
c=out(p[i],p[j],p[k]);
r=dis(c,p[k]);
}
}
}
printf("%.3f\n",r);
return ;
}