XVIII Open Cup named after E.V. Pankratiev Stage 3 Problem 10. Acceleration 物理计算

Viktor Polesov is fleeing from a raging crowd on his wonderbike. To survive, he must drive L kilometers
as fast as possible.
The contraption is powered by fire extinguishers which can be switched on in arbitrary order, strictly one
at a time. An extinguisher works for t microseconds and in that time, accelerates the bike by a meters
per second squared. If none of the extinguishers work, the bike moves at a constant speed.
Initially, the speed of the bike is zero.
Input
The first line of the input file contains a single integer M — the number of tests (1 ≤ M ≤ 104
).
Next follow M blocks. In each of these blocks, the first line contains two integers N and L — the number
of extinguishers and the length of the road in kilometers, respectively (1 ≤ N ≤ 105
, 1 ≤ L ≤ 109
). Next
come N lines with descriptions of the extinguishers. Each of them contains two integers ai and ti —
the acceleration in meters per second squared generated by the ith extinguisher and its working time in
microseconds (1 ≤ ai ≤ 105
, 1 ≤ ti ≤ 105
), respectively.
The total number of extinguishers in all tests is no greater than 105
.
Output
The output file must contain M real numbers, one per line. Each kth line is an answer to the kth test:
the minimum time in seconds necessary to cover the road of the specified length.
Answers must be printed with absolute or relative error no greater than 10−8
.
Example
input.txt output.txt
1
1 1
100000 100000
0.15
Example explanation
The mechanic-intellectual turns on the single extinguisher right away and covers half of the way in one
tenth of a second, reaching a truly orbital speed of ten kilometers per second. Keeping up this speed, he
covers the remaining half of the way in one twentieth of a second.
给定若干种加速器,求最少到达终点所需的时间;

其实很简单:贪心即可;
我们这么考虑一下:
当我们把这些加速器按加速度大小从高到低排序后,此时需要的时间是最短的;原因是什么呢?还记得以前做过的物理题吗?在 v-t 图像中,速度的曲线与x 轴围成的面积即为路程,自然是保持一个上凸的形状所需时间最短;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define sq(x) (x)*(x)
#define eps 1e-6
const int N = 2500005;

inline int read()
{
    int x = 0, k = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-')k = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x * k;
}

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}


struct node {
    double a, t;

}nd[maxn];

double vpre, vto;
double spre, sto;
double tpre, tto;

bool cmp(node x, node y) {
    return x.a > y.a;
}

int main()
{
    int M; scanf("%d", &M);
    while (M--) {
        ll n, l; scanf("%lld%lld", &n, &l);
        l = l * 1000;
        int i, j;
        for (i = 1; i <= n; i++) {
            scanf("%lf%lf", &nd[i].a, &nd[i].t);
            nd[i].t *= 0.000001;
        }
        sort(nd + 1, nd + 1 + n, cmp);
        vpre = vto = 0.0; spre = sto = 0.0;
        tpre = tto = 0.0;
        for (i = 1; i <= n; i++) {
            vto = vpre + nd[i].a*nd[i].t;
            sto = spre + vpre * nd[i].t + 0.5*nd[i].a*nd[i].t*nd[i].t;
            if (sto > l) {
                double deltt = 1.0*(-vpre + sqrt(1.0*vpre*vpre + 2 * nd[i].a*(l - spre))) / nd[i].a;
                tpre = tpre + deltt;
                vpre = vto, sto = l;    
                break;
            }
            else {
                vpre = vto, spre = sto, tpre = tpre + nd[i].t;
            }
        }
        if (sto < l) { tpre += (l - sto) / vpre; }
        printf("%.8f\n", 1.0*tpre);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/82077738