链接: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; }
究竟是我抛弃了历史,还是历史遗弃了我。