题解
这题思路好像不是那么明显。
你可以列出每个人的用时关于k的式子
那么你就要选择一个恰当的k使得
那就是说有若干条直线,你要找一个横坐标使得第n条直线在最下方,且次小的直线与它的差值最小。
显然这样的横坐标肯定是某个交点的横坐标。因此我们可以求出所有的交点,然后每个交点检验一下它是不是在最下方的交点,然后再更新下答案就好了。
这样是
代码
//计算几何
#include <cstdio>
#include <algorithm>
#include <cmath>
#define maxn 233
#define eps 1e-8
using namespace std;
int N, tot;
double k[maxn], b[maxn], dy=-1e100, s, dx;
struct point{double x, y;}pt[maxn*maxn];
point jiao(int l1, int l2)
{
point pt;
if(fabs(k[l1]-k[l2])<eps)return (point){-1,-1};
pt.x=(b[l1]-b[l2])/(k[l2]-k[l1]);
pt.y=pt.x*k[l1]+b[l1];
return pt;
}
void input()
{
int i;
double v1, v2;
scanf("%lf%d",&s,&N);
for(i=1;i<=N;i++)
{
scanf("%lf%lf",&v1,&v2);
k[i]=1/v1-1/v2;
b[i]=s/v2;
}
}
void solve()
{
int i, j;
double t, x, y;
for(i=1;i<=tot;i++)
{
x=pt[i].x, y=pt[i].y;
if(x<0 or x>s)continue;
for(j=1;j<N;j++)if(k[j]*x+b[j]<y-eps)break;
if(j==N)
if(y-k[N]*x-b[N]>dy)dy=y-k[N]*x-b[N], dx=x;
}
}
int main()
{
int i, j;
input();
for(i=1;i<N;i++)for(j=i+1;j<N;j++)pt[++tot]=jiao(i,j);
for(i=1;i<=N;i++)pt[++tot]=(point){0,b[i]}, pt[++tot]=(point){s,k[i]*s+b[i]};
solve();
if(dy<-eps)printf("NO");
else printf("%.2lf %.2lf %d",dx,s-dx,(int)(dy*3600+0.5));
return 0;
}