看了一上午平面图最短路的论文还是没看懂
很想知道旅行者那题出成在线的要怎么做(离线的你都不会好不好)
然后发现老师发了个压缩包过来。
咦,14年的SH省选题
还有数据,果断开坑。
话说第一题是考高中数学吗。。。。。。
最小椭圆覆盖
和最小圆覆盖差不多
就是要推几个公式
40+min码完是不是慢了点
话说竟然1A了真神奇
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const double eps=1e-9; const int N=500000+5; const double pi=acos(-1.0); int dcmp(double x){ if(fabs(x)<eps)return 0; return x<0?-1:1; } struct equ{ double a,b,c;//ax+by=c; }; struct point{ double x,y; bool operator == (point p){ return !dcmp(x-p.x)&&!dcmp(y-p.y); } void debug(){ printf("%lf %lf\n",x,y); } }; double sqr(double x){return x*x;} double dist(point a,point b){ return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); } point solve(equ e1,equ e2){ double D=e1.a*e2.b-e1.b*e2.a,D1=e1.c*e2.b-e2.c*e1.b,D2=e1.a*e2.c-e1.c*e2.a; return (point){D1/D,D2/D}; } double p; struct elp{ point p; double a,b; void debug(){ p.debug(); printf("%lf %lf\n",a,b); } }; equ pro(point p1,point p2){ double a=2*(p2.x-p1.x),b=2*sqr(p)*(p2.y-p1.y), c=sqr(p2.x)-sqr(p1.x)+sqr(p)*(sqr(p2.y)-sqr(p1.y)); return (equ){a,b,c}; } double calcb(point p0,point p1){ return sqrt(sqr(p1.x-p0.x)/sqr(p)+sqr(p1.y-p0.y)); } elp solve(point p1,point p2,point p3){ elp ans; ans.p=solve(pro(p1,p2),pro(p2,p3)); ans.b=calcb(ans.p,p1); ans.a=ans.b*p; return ans; } point mid(point a,point b){ return (point){(a.x+b.x)/2.0,(a.y+b.y)/2.0}; } elp solve(point p1,point p2){ elp ans; ans.p=mid(p1,p2); ans.b=calcb(ans.p,p1); ans.a=ans.b*p; return ans; } bool cover(elp e,point p){ if(!e.b)return p==e.p; return dcmp(sqr(e.b*(p.x-e.p.x))+sqr(e.a*(p.y-e.p.y))-sqr(e.a*e.b))<=0; } elp min_ellipse_cover(point *P,int n){ random_shuffle(P,P+n); elp ans; ans.p=P[0];ans.a=ans.b=0; for(int i=1;i<n;i++) if(!cover(ans,P[i])){ ans.p=P[i];ans.a=ans.b=0; for(int j=0;j<i;j++) if(!cover(ans,P[j])){ ans=solve(P[i],P[j]); for(int k=0;k<j;k++) if(!cover(ans,P[k])) ans=solve(P[i],P[j],P[k]); } } return ans; } point t[N]; point rotate(point p,double a){ return (point){p.x*cos(a)+p.y*sin(a),p.y*cos(a)-p.x*sin(a)}; } int main(){ //freopen("a.in","r",stdin); int n;scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lf%lf",&t[i].x,&t[i].y); double a;scanf("%lf%lf",&a,&p); a=a/180.0*pi; for(int i=0;i<n;i++)t[i]=rotate(t[i],a); printf("%.3lf\n",min_ellipse_cover(t,n).b); return 0; }
TM才发现脑残了。
直接把横坐标除以p,然后做最小圆覆盖就好了