hdu 4717(三分) The Moving Points

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4717

n个点,给出初始坐标和移动的速度和移动的方向,求在哪一时刻任意两点之间的距离的最大值的最小。

对于最大值的最小问题首先就会想到二分,然而由于两点之间的距离是呈抛物线状,所以三分的方法又浮上脑海,当然二分也可以做,不过思维上更复杂一些

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 const double eps = 0.000001;
 9 const int M = 310;
10 int n;
11 
12 struct point{
13     double x,y,vx,vy;
14     void read(){scanf("%lf%lf%lf%lf",&x,&y,&vx,&vy);}
15 }po[M];
16 
17 double max(double x,double y){return x>y?x:y;}
18 
19 double dis(double x1,double y1,double x2,double y2)
20 {
21     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
22 }
23 
24 double cal(double t)
25 {
26     double ans=0;
27     for (int i=1 ; i<=n ; i++){
28         for (int j=i+1 ; j<=n ; j++){
29             double num=dis(po[i].x+t*po[i].vx,po[i].y+t*po[i].vy,po[j].x+t*po[j].vx,po[j].y+t*po[j].vy);
30             ans=max(num,ans);
31         }
32     }
33     return ans;
34 }
35 
36 double solve(double l,double r)
37 {
38     while (r-l>=eps)
39     {
40         double mid1=(l*2+r)/3;
41         double mid2=(l+r*2)/3;
42         if (cal(mid2)-cal(mid1)>eps)
43             r=mid2;
44         else
45             l=mid1;
46     }
47     return l;
48 }
49 
50 int main()
51 {
52     int t,cas=0;
53     scanf("%d",&t);
54     while (t--)
55     {
56         scanf("%d",&n);
57         for (int i=1 ; i<=n ; i++)
58             po[i].read();
59         double ans=solve(0,1e8);
60         printf("Case #%d: ", ++cas);
61         if (n==1) printf("0.00 0.00
");
62         else printf("%.2lf %.2lf
",ans,cal(ans));
63     }
64     return 0;
65 }
原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5499406.html