HDU 5935 Car 题解
题目大意
给定位移轴上的 \(n\)个点,一个人从 \(x=0\) 原点出发,给定的位移轴上的点到达的时间未知,但一定是整数时刻,Ruins 的速度是一个不降的实数曲线,问最短经过多少时间可以走完。
题解
由于时间要短,所以速度要尽可能大,我们考虑速度最快的最后,由于每两个给定位置经过的时间差最小只能是 \(1\)(要求在整时刻上),于是我们贪心地把最后的速度 \(\displaystyle v=\frac{a[i]-a[i-1]}{1}\),然后尝试着按这个速度往前走。
由于要求必须走整时刻到给定点,如果以当前速度可以整倍数的走完,则直接走就可以,若不能,则意味着我们必须改变速度,由于速度一定要降低,先设一个准确的实数时间 \(\displaystyle t=\frac{\Delta s}{v}\),然后对 \(t\) 下取整,由于下取整后刚好走不完,我们让新的速度 \(\displaystyle v'=\frac{\Delta s}{t+1}\)(即希望把速度稍微放慢一点,使得恰好在整时刻走完),即取到尽可能大的合法速度,以此类推一直走到 \(0\) 即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
   |  #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> #include <iostream> #include <cassert> #include <cmath> using namespace std; typedef long long ll; typedef long double ld;   template <typename _Tp> void read(_Tp &a, char c = 0, int f = 1) {     for(c = getchar(); !isdigit(c); c = getchar()) if(c == '-') f = -1;     for(a = 0; isdigit(c); a = a * 10 + c - '0', c = getchar()); a *= f; }   template <typename _Tp> void write(_Tp a) {     if(a < 0) putchar('-'), a = -a;     if(a > 9) write(a / 10); putchar(a % 10 + '0'); }
  const int N = 1e5 + 5; const ld eps = 1e-9;
  int n; int a[N];
  int main() {          int T;     read(T);     for(int _T = 1; _T <= T; _T++) {         ll ans = 0;         read(n);         for(int i = 1; i <= n; i++) {             read(a[i]);         }         ld v = -1;         for(int i = n; i >= 1; i--) {             ld ds = a[i] - a[i - 1];             if(v < 0) {                 v = ds;                 ans++;             } else {                 ll t = ds / v;                 ld _s = v * t;                 if(fabs(ds - _s) < eps) {                     ans += t;                 } else {                     v = ds / (t + 1);                     ans += t + 1;                 }             }         }         printf("Case #%d: ", _T), write(ans), putchar('\n');     }     return 0; }
 
  |