1. 程式人生 > >The Moving Points

The Moving Points

There are N points in total. Every point moves in certain direction and certain speed. We want to know at what time that the largest distance between any two points would be minimum. And also, we require you to calculate that minimum distance. We guarantee that no two points will move in exactly same speed and direction.

 

Input

The rst line has a number T (T <= 10) , indicating the number of test cases. 
For each test case, first line has a single number N (N <= 300), which is the number of points. 
For next N lines, each come with four integers X i, Y i, VX i and VY i (-10 6 <= X i, Y i <= 10 6, -10 2 <= VX i , VY i <= 10 2), (X i, Y i) is the position of the i th point, and (VX i , VY i) is its speed with direction. That is to say, after 1 second, this point will move to (X i + VX i , Y i + VY i).

 

Output

For test case X, output "Case #X: " first, then output two numbers, rounded to 0.01, as the answer of time and distance.

 

Sample Input

 

2 2 0 0 1 0 2 0 -1 0 2 0 0 1 0 2 1 -1 0

 

Sample Output

 

Case #1: 1.00 0.00 Case #2: 1.00 1.00

題目的意思是給你n個點,每個點按特定方向移動,題目要我們求出在t時刻的點之間最大距離的最小值(每個時刻點之間的距離不一樣,n個點就有(n-1)!個線段,找出其中最大的記做(st i),t在變,每個時刻的最大值(st n)也在變,找出最小值即可)。

點之間的距離函式我們不難想到是個二次函式,且開口肯定是向上的,最低點就是我們要找的最小值。因此我們可以對時間進行三分操作(每個時刻點的距離是隨時間變化的),找到最小值。

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#define  LL long long
#define  ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
using namespace std;
const int MAXN = 2005;
const int N = 15;
const double eps=1e-6;
double x[MAXN];
double y[MAXN];
double xv[MAXN];
double yv[MAXN];
int n;
double cal(double t)//這個函式是算在t時刻,所有點中距離最大的值
{
    double sum=0;
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            double x1=x[i]+xv[i]*t;
            double y1=y[i]+yv[i]*t;
            double x2=x[j]+xv[j]*t;
            double y2=y[j]+yv[j]*t;
            double cot=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
            sum=max(sum,cot);
        }
    }
    return sum;
}
double thr()//三分時間找出最小值
{
    double l=0,r=1e10;
    while(r-l>=eps){
    double mid=(l+r)/2;
    double midmid=(r+mid)/2;
    double cot1=cal(mid);
    double cot2=cal(midmid);
    if(cot1<cot2) r=midmid-eps;
    else l=mid+eps;
   }
   return l;
}
int main()
{

    int T;
    int cot=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);

        int i;
        for(i=0;i<n;i++) scanf("%lf%lf%lf%lf",&x[i],&y[i],&xv[i],&yv[i]);
        double h=thr();
        printf("Case #%d: %.2lf %.2lf\n",cot++,h,cal(h));
    }
    return 0;
}