【计算几何】【二分】【随机增量法】hdu6167 Missile Interception

n个半径为R的圆是否有公共部分,等价于询问是否存在一个半径小于R的圆,能覆盖所有n个圆的圆心。

对这n个点求最小圆覆盖即可。从网上扒了个随机增量法的代码。

这样算上二分,复杂度就是nlogn了。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps=0.000000001;
int n;
double V,x[103],y[103],dx[103],dy[103],v[103],cx[103],cy[103];
struct node  
{  
    double x,y;  
};   
node p[1000001];  
double r;  
node O;  
  
double dist(node a,node b)  
{
    return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) );  
}
void calc(double a,double b,double c,double d,double e,double f)
{
    O.y=(c*d-f*a)/(b*d-e*a);  
    O.x=(c*e-f*b)/(a*e-b*d);  
}
double get()
{
    for (int i=1;i<=n;++i)   
    {  
        p[i].x=cx[i];
        p[i].y=cy[i];
    }  
     O=p[1];r=0;                
       
     for(int i=2;i<=n;++i)        
     if(dist(O,p[i])>r+1e-6)   
     {  
         O=p[i];r=0;  
         for (int j=1;j<=i-1;++j)      
         if (dist(O,p[j])>r+1e-6)   
         {  
             O.x=(p[i].x+p[j].x)/2;  
             O.y=(p[i].y+p[j].y)/2;  
             r=dist(O,p[j]);  
             for (int k=1;k<=j-1;++k)     
             if (dist(O,p[k])>r+1e-6)  
             {  
                calc(p[j].x-p[i].x,p[j].y-p[i].y,(p[j].x*p[j].x+p[j].y*p[j].y-p[i].x*p[i].x-p[i].y*p[i].y)/2,  
                     p[k].x-p[i].x,p[k].y-p[i].y,(p[k].x*p[k].x+p[k].y*p[k].y-p[i].x*p[i].x-p[i].y*p[i].y)/2);   
               r=dist(O,p[k]);  
             }   
         }  
     }  
     return r;
}
bool check(double t)
{
    for(int i=1;i<=n;++i)
    {
        cx[i]=x[i]+dx[i]*t*v[i];
        cy[i]=y[i]+dy[i]*t*v[i];
    }
    return get()<t*V+eps;
}
int main()
{
    while(scanf("%d%lf",&n,&V)!=EOF)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%lf%lf%lf%lf%lf",&x[i],&y[i],&dx[i],&dy[i],&v[i]);
            double l=sqrt(dx[i]*dx[i]+dy[i]*dy[i]);
            dx[i]/=l;
            dy[i]/=l;
        }
        double l=0,r=9999999;
        while(l<r-eps)
        {
            double mid=(l+r)*0.5;
            if(check(mid)) r=mid;
            else l=mid;
        }
        printf("%.4lf\n",r);
    }
    return 0;
}
posted @ 2017-08-23 00:28  AutSky_JadeK  阅读(316)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト