题目: 给出N个点,给出这N个点的初始位置和速度,求在什么时候他们之间的最大距离最短。
思路: 考虑时间,设在某个时间点的时候他们的最大距离最短。
可得得出求距离的公式……其实就是两点间距离的那个公式……求出所有的点之间的距离的最大,这样总共是C(N,2)次啦。
循环一百次啊一百次。。。
考虑到 两个点之间的距离正常应该是先变小再变大,类似于抛物线的结构……一直在变大的只考虑一开始就行,还是一样的……
就是用三分法,浮点型的……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int N,T;
struct node//点结构
{
double x,y,vx,vy;
}p[305];
double getDis(node a, node b)//两点间距离
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double fuck(double time)//找出某个时间点所有点之间的最大距离的
{
double sum = 0.0;
node tem[305];
for(int i = 0;i<N;++i)
{
tem[i].x = p[i].x + p[i].vx * time;
tem[i].y = p[i].y + p[i].vy * time;
}
for(int i = 0;i<N;++i)
{
for(int j = i+1;j<N;++j)
{
sum = max(sum, getDis(tem[i], tem[j]));
}
}
return sum;
}
double solve(double l, double r)//三分主体
{
int tt = 100;
while(tt--)
{
double m1 = (l*2+r)/3.0;
double m2 = (l+r*2)/3.0;
if(fuck(m1) < fuck(m2))
r = m2;
else
l = m1;
}
return l;
}
int main()
{
int cnt = 0;
scanf("%d",&T);
while(T--)
{
cnt++;
scanf("%d",&N);
for(int i = 0;i<N;++i)
{
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].vx,&p[i].vy);
}
printf("Case #%d: ",cnt);
if(N == 1)//特判情况
{
printf("0.00 0.00\n");
continue;
}
double time = solve(0.0,10000000.0);
printf("%.2lf %.2lf\n",time,fuck(time));
}
return 0;
}