Hint里的没有数据是肿么回事,仿佛是在刻意地逗我笑
首先这是个贪心题
我们考虑首先让耗油量尽可能地低
上坡段是必须耗油的,速度先置为0
下坡段速度可以提升一下,达到耗油为0即可
平底自然速度为0
然后找到当前速度最小的路段,提升它的速度与次小的平齐,注意不要超过限制
直到提升不了为止,最后结算一下
如果发现最小和次小速度相等就把他们合并了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N=10000+5;
const double eps=1e-9;
double a,b,f,vmax;
struct Node{
double v,l;
bool operator < (const Node &rhs)const{
return v>rhs.v;
}
};
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
double sqr(double x){return x*x;}
int main(){
//freopen("a.in","r",stdin);
int T;scanf("%d",&T);
while(T--){
int n;scanf("%lf%lf%lf%lf%d",&a,&b,&vmax,&f,&n);
priority_queue<Node>q;
bool flag=true;
for(int i=1;i<=n;i++){
double x,y;scanf("%lf%lf",&x,&y);
x/=1000.0;y/=1000.0;
double l=sqrt(sqr(x)+sqr(y)),s=y/x;
int d=dcmp(s);
if(d>0){
f-=l*b*s;
q.push((Node){0,l});
if(dcmp(f)<=0)flag=false;
}else if(d<0){
double v=min(-b/a*s,vmax);
q.push((Node){v,l});
}else q.push((Node){0,l});
}
if(!flag){
puts("IMPOSSIBLE");
continue;
}
q.push((Node){vmax,0});
double ans=0;
while(dcmp(f)>0&&!q.empty()){
Node t=q.top();q.pop();
if(!dcmp(t.v-vmax))ans+=t.l/t.v;
else if(dcmp(t.v-q.top().v)){
double delta=f/(a*t.l);
if(dcmp(t.v+delta-q.top().v)>=0){
Node tt=q.top();q.pop();
delta=tt.v-t.v;
q.push((Node){tt.v,t.l+tt.l});
}else{
t.v+=delta;
q.push(t);
}
f-=delta*a*t.l;
}else{
Node tt=q.top();q.pop();
q.push((Node){t.v,t.l+tt.l});
}
}
while(!q.empty()){
Node t=q.top();q.pop();
ans+=t.l/t.v;
}
printf("%.5lf\n",ans);
}
return 0;
}