zoukankan      html  css  js  c++  java
  • bzoj2765[JLOI2010]铁人双项比赛

    题意:铁人双项比赛由长跑和骑自行车组成,参赛选手必须先完成k公里的长跑,然后完成r公里的骑车,才能到达终点。参赛选手有的擅长长跑,有的擅长骑车。

    如果总赛程s=k+r一定,那么K越大,对擅长长跑的选手越有利;k越小,对擅长骑车的选手越有利。

    现在给定总赛程s,以及每个选手长跑和骑车的平均速度,请你求出对于某个指定的选手最有利的k和r。

    所谓最有利,是指选择了这个k和r后,该选手可以获得冠军,且领先第2名尽量地多。

    讲道理这题应该有SpecialJudge,但是BZOJ是在有多种方案时输出k最小的方案,题面上还没说…WA了一屏....

    并不知道半平面交是什么东西(半瓶面胶),我写的是二分答案…首先我们把速度的单位从 千米/小时 转为 秒/千米,然后用i号选手的骑车速度减去n号选手的骑车速度,就表示i号选手和n号选手同时骑单位长度的车,n号选手会领先i号选手多少秒(负值表示n号选手落后i号选手).

    接下来我们会发现,如果每长跑1千米n号选手会领先i号选手v1秒,每骑1千米车n号选手会领先i号选手v2秒(v1,v2均可能为负),二分答案时要求n号选手必须领先i号选手不少于ans秒,我们就可以确定一个关于k的不等式k*v1+(s-k)*v2>=ans,这里只有k未知,所以可以解出这个不等式.

    每二分一个答案,一共得到n-1个形如”k>a”或”k<b”的不等式,只要判断这个不等式组有没有解即可.注意v1==v2的地方需要特判.最后一定要注意:输出解的时候k尽量小,所以最后利用二分出的答案解一遍不等式组,输出的时候用k的下界输出..

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=105;
    double v1[maxn],v2[maxn];
    int s,n;
    bool check(double ans){
        double upper=s,lower=0;    
        for(int i=1;i<n;++i){
            if(v1[i]==v2[i]){
                if(s*v1[i]<ans)return false;
            }
            else if(v1[i]<v2[i])upper=min(upper,(ans-v2[i]*s)/(v1[i]-v2[i]));
            else lower=max(lower,(ans-v2[i]*s)/(v1[i]-v2[i]));
        }
        return upper>=lower;
    }
    void work(double ans){
        double upper=s,lower=0;    
        for(int i=1;i<n;++i){
            if(v1[i]==v2[i])continue;
            else if(v1[i]<v2[i])upper=min(upper,(ans-v2[i]*s)/(v1[i]-v2[i]));
            else lower=max(lower,(ans-v2[i]*s)/(v1[i]-v2[i]));
        }
        printf("%.2f %.2f ",lower,s-lower);
    }
    int main(){
        scanf("%d%d",&s,&n);
        for(int i=1;i<=n;++i){
            scanf("%lf%lf",v1+i,v2+i);
            v1[i]=3600/v1[i];v2[i]=3600/v2[i];
        }
        for(int i=1;i<n;++i){
            v1[i]-=v1[n];v2[i]-=v2[n];
        }
        double l=-1,r=1e50;
        while(r-l>=1e-8){
            double mid=(l+r)/2.0;
            if(check(mid))l=mid;
            else r=mid;
        }
        
        if(r<0)printf("NO
    ");
        else{
            work(r);
            printf("%.0f
    ",r);
        }
        return 0;
    }
  • 相关阅读:
    [HAOI2008]硬币购物
    [SCOI2005]骑士精神
    [ZJOI2007]最大半联通子图
    [HAOI2007]反素数
    [SCOI2005]繁忙的都市
    小凯的疑惑
    5月16日vj题解
    周六题目前四题详解
    Codeforces Round #629 (Div. 3)做题记录
    Codeforces Round #570 (Div. 3) B. Equalize Prices
  • 原文地址:https://www.cnblogs.com/liu-runda/p/5995316.html
Copyright © 2011-2022 走看看