BZOJ 1337 最小圆覆盖 随机增量法

题意:链接方法:随机增量法解析:首先把所有点打乱。然后枚举第一个点,如果不在当前的圆内则把它设为圆心.再枚举第二个点,如果不在当前的圆内则把圆设为其与第一个点的距离为直径的圆。再枚举第三个点,如果不在当前的圆内则把圆设为这三个点构成三角形的外接圆。然后最后就是答案了。别问我这为什么是对的- -!复杂度期望O(n),我是信了。代码:;struct Point{double x,y;friend istream& operator >> (istream &_,Point &a){scanf(“%lf%lf”,&a.x,&a.y);return _;}Point(){}Point(double _x,double _y):x(_x),y(_y){}Point operator + (const Point &a){return Point(x+a.x,y+a.y);}Point operator – (const Point &a){return Point(x-a.x,y-a.y);}Point operator * (double rate){return Point(x*rate,y*rate);}double operator * (const Point &a){return x*a.x+y*a.y;}double operator ^ (const Point &a){return x*a.y-y*a.x;}}pt[N];struct Line{Point p,v;Line(){}Line(Point a,Point b):p(a),v(b){}};struct Circle{Point p;double R;Circle(){}Circle(Point _p,double _R):p(_p),R(_R){}}ans;double dis(Point &a,Point &b){return sqrt((a-b)*(a-b));}bool is_in_cir(Point &p,Circle &c){return dis(p,c.p)<=c.R;}Point Get_Intersection(Line &l1,Line &l2){Point u=l1.p-l2.p;double tmp=(l2.v^u)/(l1.v^l2.v);return l1.p+l1.v*tmp; }Point rotate (Point a){return Point(-a.y,a.x);}int n;int main(){srand(19990329);scanf(“%d”,&n);for(int i=1;i<=n;i++)cin>>pt[i];random_shuffle(pt+1,pt+n+1);for(int i=1;i<=n;i++){if(!is_in_cir(pt[i],ans)){ans.p=pt[i];for(int j=1;j<i;j++){if(!is_in_cir(pt[j],ans)){ans.p=(pt[i]+pt[j])*0.5;ans.R=dis(pt[i],pt[j])*0.5;for(int k=1;k<j;k++){if(!is_in_cir(pt[k],ans)){Line l1((pt[i]+pt[j])*0.5,rotate(pt[i]-pt[j]));Line l2((pt[i]+pt[k])*0.5,rotate(pt[i]-pt[k]));ans.p=Get_Intersection(l1,l2);ans.R=dis(ans.p,pt[i]);}}}}}}cout<<fixed<<setprecision(3)<<ans.R<<endl;}

,人生的大部份时间里,承诺同义词是束缚,奈何我们向往束缚。

BZOJ 1337 最小圆覆盖 随机增量法

相关文章:

你感兴趣的文章:

标签云: