题目大意
T组数据
每组数据给n个点的坐标(Xi,Yi)和他们每秒在x方向和y方向上的移动速度Vxi,VYi
求一个时间使得任意两点之间的最大距离最小
同时输出最小距离
(-10^6 <= Xi, Yi <= 10^6 , -10^2 <= VXi , VYi <= 10^2 )
思路
这题看到最大值最小首先想到的就是三分,事实上他们的最大距离是一个开口向上的抛物线,三分一下时间就可使得最大距离最小
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#define N 10001
#define eps 1e-6
#define inf 1e12
using namespace std;
int n,cas=0;
struct pppp
{
double x,y,vx,vy;
}a[N];
inline double dis(int x,int y,double z){
double x1n=a[x].x+z*a[x].vx,x2n=a[y].x+z*a[y].vx;
double y1n=a[x].y+z*a[x].vy,y2n=a[y].y+z*a[y].vy;
return sqrt((x1n-x2n)*(x1n-x2n)+(y1n-y2n)*(y1n-y2n));
}
inline double ys(double x){
double ans=0;
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
ans=max(ans,dis(i,j,x));
}
}
return ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
double t,ans=inf;
for(int i=1;i<=n;++i){
scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].vx,&a[i].vy);
}
printf("Case #%d: ",++cas);
double l,r,mid1,mid2;
l=0;r=2147483640;
while(l<r-eps){
mid1=(2*l+r)/3;
mid2=(l+2*r)/3;
double w1=ys(mid1),w2=ys(mid2);
if(w1<w2){
r=mid2;
}
else l=mid1;
if(ans>w1) ans=w1,t=mid1;
if(ans>w2) ans=w2,t=mid2;
}
printf("%.2lf %.2lf\n",t,ans);
}
return 0;
}