链接: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 }