其他分享
首页 > 其他分享> > ICPC2021上海区域赛 D.Walker(二分、分类讨论)

ICPC2021上海区域赛 D.Walker(二分、分类讨论)

作者:互联网

#include<bits/stdc++.h>
using namespace std;
int t;
double n, pa, pb, va, vb;
int main()
{
    cin >> t;
    while(t --)
    {
        double res = 1000000000;
        cin >> n >> pa >> va >> pb >> vb;
        if(pa > pb) swap(pa, pb), swap(va, vb); //始终让a在左侧
        res = min( (n + min(pa, n - pa)) / va, (n + min(pb, n - pb)) / vb); //a、b独自走完一条线段
        res = min(res, max( (n - pa) / va, pb / vb ) ); //a、b相向而行走到边界
        // 二分枚举一个点x, a、b负责覆盖x的左侧、右侧
        double l = pa, r = pb;
        while(r - l > 1e-7)
        {
            double mid = (l + r) / 2.0;
            double ta = min(pa + mid, 2 * mid - pa) / va; //先向左到起点后返回mid/先向右到mid再返回起点
            double tb = min(n + pb - 2 * mid, 2 * n - pb - mid) / vb;
            res = min(res, max(ta, tb)); //类似木桶效应
            if(ta > tb) r = mid; //缩小a的时间
            else l = mid; //增加a的时间
        }
        printf("%.6lf\n", res);
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int t;
double n, pa, pb, va, vb;
int main()
{
    cin >> t;
    while(t --)
    {
        double res = 1000000000;
        cin >> n >> pa >> va >> pb >> vb;
        if(pa > pb) swap(pa, pb), swap(va, vb); //始终让a在左侧
        res = min( (n + min(pa, n - pa)) / va, (n + min(pb, n - pb)) / vb); //a、b独自走完一条线段
        res = min(res, max( (n - pa) / va, pb / vb ) ); //a、b相向而行走到边界
        // 二分枚举一个点x, a、b负责覆盖x的左侧、右侧
        double l = pa, r = pb;
        for(int i = 1; i <= 100; i++)
        {
            double mid = (l + r) / 2.0;
            double ta = min(pa + mid, 2 * mid - pa) / va; //先向左到起点后返回mid/先向右到mid再返回起点
            double tb = min(n + pb - 2 * mid, 2 * n - pb - mid) / vb;
            res = min(res, max(ta, tb)); //类似木桶效应
            if(ta > tb) r = mid; //缩小a的时间
            else l = mid; //增加a的时间
        }
        printf("%.6lf\n", res);
    }
    return 0;
}

标签:二分,va,ICPC2021,min,res,vb,pb,pa,Walker
来源: https://www.cnblogs.com/K2MnO4/p/14882717.html