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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#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 @   AutSky_JadeK  阅读(316)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト
点击右上角即可分享
微信分享提示