HDU - 4717 Los puntos móviles

Descripción del problema:

Hay N puntos en total. Cada punto se mueve en cierta dirección y con cierta velocidad. Queremos saber en qué momento la mayor distancia entre dos puntos sería mínima. Y también, le pedimos que calcule esa distancia mínima. Garantizamos que no hay dos puntos que se muevan exactamente con la misma velocidad y dirección.

Descripción de entrada:

La primera línea tiene un número T (T <= 10), que indica el número de casos de prueba.
Para cada caso de prueba, la primera línea tiene un solo número N (N <= 300), que es el número de puntos.
Para las siguientes N líneas, cada una viene con cuatro números enteros Xi, Yi, VXi y VYi (-106 <= Xi, Yi <= 106, -102 <= VXi, VYi <= 102), (Xi, Yi) es la posición de el i-ésimo punto, y (VXi, VYi) es su velocidad con dirección. Es decir, después de 1 segundo, este punto se moverá a (Xi + VXi, Yi + VYi).

Descripción de salida:

Para el caso de prueba X, primero muestre "Caso #X:", luego envíe dos números, redondeados a 0.01, como la respuesta de tiempo y distancia.

ENTRADA DE MUESTRA:

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

MUESTRA DE SALIDA:

Caso # 1: 1.00 0.00
Caso # 2: 1.00 1.00

Ideas:

La conciencia del sujeto es el valor mínimo de la distancia máxima entre nosotros dos puntos. Use la dicotomía para encontrar el valor mínimo, escriba una función de antemano para obtener la distancia entre dos puntos, preste atención para asegurarse de que la precisión sea lo suficientemente pequeña en la dicotomía.

Código AC:

#include <bits/stdc++.h>
using namespace std;
int n;
double a[1000],b[1000],c[1000],d[1000];
double distance(int m,int n,double t)
{
    
    
    double x1=a[m]+t*c[m],x2=a[n]+t*c[n];
    double y1=b[m]+t*d[m],y2=b[n]+t*d[n];
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double check(double t)
{
    
    
    double ans=0.0;
    for(int i=1;i<=n;i++)
    {
    
    
        for(int j=i+1;j<=n;j++)
        {
    
    
            ans=max(ans,distance(i,j,t));
        }
    }
    return ans;
}

int main()
{
    
    
    int T;
    cin>>T;
    int cas=0;
    while(T--)
    {
    
    
        cin>>n;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        for(int i=1;i<=n;i++)
        {
    
    
            scanf("%lf%lf%lf%lf",&a[i],&b[i],&c[i],&d[i]);
        }
        double l=0.0,r=100000000000.0,time=0.0,path=10000000000000.0;
        while(l+1e-11<=r)
        {
    
    
            double middle1=(l+r)/2;
            double middle2=(middle1+r)/2;
            if(check(middle1)<=check(middle2))
                r=middle2;
            else l=middle1;
            if(path>check(l))
            {
    
    
                time=l;
                path=check(l);
            }
        }
        cout<<"Case #"<<++cas<<": "<<fixed<<setprecision(2)<<time<<' '<<path<<endl;
    }
    return 0;
}


Supongo que te gusta

Origin blog.csdn.net/m0_51727949/article/details/115187650
Recomendado
Clasificación