链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1326
题解
用手机写代码可还行qwq
对于每个人,
y
=
(
1
v
1
−
1
v
2
)
x
+
r
v
1
y=(\frac{1}{v_1}-\frac{1}{v_2})x+\frac{r}{v_1}
y=(v11−v21)x+v1r,其中
x
x
x是第一项运动的距离
我求出
n
2
n^2
n2个交点,答案肯定就在这
n
2
n^2
n2个交点之中取到(一次函数的单调性)
代码
#include <cstdio>
#include <algorithm>
#define eps 1e-8
#define maxn 1000
#define dinf 1e100
using namespace std;
int tot, n;
double t, v1[maxn], v2[maxn], k[maxn], b[maxn], x[maxn];
double cross(double k1, double b1, double k2, double b2)
{
return (b2-b1)/(k1-k2);
}
void init()
{
int i, j;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lf%lf",v1+i,v2+i);
for(i=1;i<=n;i++)
{
k[i] = (1/v1[i]-1/v2[i]);
b[i] = t/v2[i];
}
tot = 0;
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
double tmp = cross(k[i],b[i],k[j],b[j]);
if(tmp > eps and tmp < t-eps)x[++tot]=tmp;
}
x[++tot] = 0;
x[++tot] = t;
}
void work()
{
double r, mn, ans(-dinf);
int i, j;
for(i=1;i<=tot;i++)
{
mn = dinf;
for(j=1;j<n;j++)
{
mn = min(mn,k[j]*x[i]+b[j]);
}
if(mn-k[n]*x[i]-b[n] > ans)
{
ans = mn-k[n]*x[i]-b[n];
r=x[i];
}
}
if(ans>-eps)
{
printf("The cheater can win by %d seconds with r = %.2lfkm and k = %.2lfkm.\n",int(ans*3600+0.5),r,t-r);
}
else
{
printf("The cheater cannot win.\n");
}
}
int main()
{
while(~scanf("%lf",&t))
{
init();
work();
}
return 0;
}