NC16787. [NOIP1999]旅行家的预算
描述
输入描述
第一行:D1,C,D2,P,N。
接下来有N行。
第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。
输出描述
所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
示例1
输入:
275.6 11.9 27.4 2.8 2 102.0 2.9 220.0 2.2
输出:
26.95
Pascal(fpc 3.0.2) 解法, 执行用时: 1ms, 内存消耗: 256K, 提交时间: 2018-08-02 11:55:37
var d1,d2,c,oil,w:extended; n,i,j:longint; d,p:array[1..100000] of extended; f:boolean; begin readln(d1,c,d2,p[0],n); for i:=1 to n do readln(d[i],p[i]); d[n+1]:=d1; for i:=0 to n do begin oil:=oil-(d[i]-d[i-1])/d2; if d[i+1]-d[i]>c*d2 then begin writeln('No Solution'); halt; end; f:=false; for j:=i+1 to n+1 do begin if d[j]-d[i]>c*d2 then break; if p[j]<p[i] then begin f:=true; break; end; end; if (oil<(d[j]-d[i])/d2) and f then begin w:=w+((d[j]-d[i])/d2-oil)*p[i]; oil:=(d[j]-d[i])/d2; end else if not f then begin w:=w+(c-oil)*p[i]; oil:=c; end; end; writeln(w:0:2); end.
C++(g++ 7.5.0) 解法, 执行用时: 2ms, 内存消耗: 424K, 提交时间: 2023-03-04 17:04:50
#include<bits/stdc++.h> using namespace std; double d1,c,d2,p,d[10],v[10],last,ans; int n; int main(){ scanf("%lf%lf%lf%lf%d",&d1,&c,&d2,&p,&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&d[i],&v[i]); d[n+1]=d1;v[0]=p; for(int i=1;i<=n;i++){ if(d[i+1]-d[i]>c*d2){ printf("No Solution\n"); return 0; } } int j; for(int i=0;i<=n;i=j){ for(j=i+1;j<=n+1;j++){ if(d[j]-d[i]>c*d2){ j--; break; } if(v[j]<v[i]) break; } if(v[j]<v[i]){ ans+=((d[j]-d[i])/d2-last)*v[i]; last=0; } else { ans+=(c-last)*v[i]; last=c-(d[j]-d[i])/d2; } } printf("%.2lf\n",ans); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 480K, 提交时间: 2018-11-09 18:34:39
#include<cstdio> #define M 100000 int n,i,j; double o,d1,c,d2,s,m,d[M],p[M]; int main(){ scanf("%lf%lf%lf%lf%d",&d1,&c,&d2,&p[0],&n); d[n+1]=d1; for(i=1;i<=n;++i)scanf("%lf%lf",&d[i],&p[i]); for(i=1;i<=n+1;++i) if(d[i]-d[i-1]>c*d2)return 0*puts("No Solution"); i=0; while(i<=n){ j=i+1; while(d[j]-d[i]<=d2*c&&p[i]<=p[j])++j; if(d[j]-d[i]<=d2*c){ s=d[j]-d[i]; if(o<s/d2)m+=(s/d2-o)*p[i],o=0; else o-=s/d2; i=j; } else{ m+=(c-o)*p[i]; o=c-(d[++i]-d[i-1])/d2; } } printf("%0.2lf",m); return 0; }