2013杭电 warm 2, hdu 4717 The Moving Points 三分

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4717

第一次写三分,这个解法是学解题报告的,感谢原作者。


首先对每对点对,他们的距离关于时间t是二次函数,现在就是求c[n][2] 个二次函数,每个点取最大值构成的函数的极值。  

由于每个子函数都是先减后增,或者对称轴小于0,直接单增,他们的max一定也保持着这个性质 (具体证明和n个下凸函数max还是下凸函数很像?)


然后取100次精度就够了


代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

int x[300],y[300],vx[300],vy[300];

int n;
double f(double t)
{
   double max=0;
   for(int i=0;i<n;i++)
    for(int j=i+1;j<n;j++)
     {
        double cur=(x[i]+t*vx[i]-x[j]-t*vx[j])*(x[i]+t*vx[i]-x[j]-t*vx[j])+(y[i]+t*vy[i]-y[j]-t*vy[j])*(y[i]+t*vy[i]-y[j]-t*vy[j]);
        if(cur>max)  max=cur;
     }

   return max;
}
int main()
{
    int T;
    cin>>T;

    int index=0;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
         scanf("%d%d%d%d",&x[i],&y[i],&vx[i],&vy[i]);

        double l=0,r=100000000,m1,m2;
        for(int i=0;i<100;i++)
        {
           m1=l+(r-l)/3;
           m2=r-(r-l)/3;

           if(f(m1)<f(m2))    r=m2;
           else   l=m1;
        }

        double ans=sqrt(f(l));

        printf("Case #%d: %.2lf %.2lf\n",++index,l,ans);

    }
}


posted @ 2013-09-23 23:30  814jingqi  阅读(121)  评论(0编辑  收藏  举报