链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1326

题意:题意参见《训练指南》185页

思路:和上一道题思路差不多,不过这一道题求得是最大值。对于一个r,计算出标号为0到n-2个人所需的时间,在这些值里取最小的值smin,也就是跑得最快的。计算出第n-1个人在这个r下所需的时间s0,由于题目要求指定选手要和第二名的时间差距尽量大,即要使smin-s0的值最大,用三分法来求这个最大值。另外,当smin-s0<0,则说明找不到满足条件的r.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cassert>
#include<cstring>
#include<algorithm>
using namespace std;

const double eps=1e-9;
const int maxn=25;
double vr[maxn],vc[maxn];
int t,n;
double S(double x)
{
    double s0=x/vr[n-1]+(t-x)/vc[n-1];
    double minm=1e100;
    for(int i=0; i<n-1; ++i)
        minm=min(minm,x/vr[i]+(t-x)/vc[i]);
    return minm-s0;
}
double ternary()
{
    double x=0,y=t,m1,m2;
    for(int i=0; i<150; i++)
    {
        m1=x+(y-x)/3;
        m2=y-(y-x)/3;
//        m1=(2*x+y)/3;m2=(x+2*y)/3;
        if(S(m1)>S(m2)) y=m2;
        else x=m1;
    }
    return (m1+m2)/2;
}
int main()
{
    while(~scanf("%d",&t))
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%lf%lf",&vr[i],&vc[i]);
        double r=ternary();
        double tm=S(r);
        if(tm<0.0) printf("The cheater cannot win.\n");
        else
           printf("The cheater can win by %.0lf seconds with r = %.2lfkm and k = %.2lfkm.\n",tm*3600,r,t-r);
    }
    return 0;
}

 

 

 posted on 2013-09-09 15:54  ∑求和  阅读(342)  评论(0编辑  收藏  举报