牛客小白月赛-鲲

时间限制 1000ms 空间限制 262144K

题目:

   北冥有鱼,其名为鲲,鲲之大,不知其几千里也。

                                        ——《庄子·逍遥游》

    HtBest有一条可爱的小鲲,HtBest想和与小鲲比赛游泳,我们可以把游泳池看成一个圆环,两人从起点游一圈回到起点即可完成比赛。两人在距离小于k时(距离指的是在环上的距离,而非直线距离),他们会互相监督对方有没有全速向前游,如果发现有一方没有全速向前游,则视为作弊,聪明的HtBest为了省力(更为了赢得比赛),可以选择在两者相距超过k的时候,立马掉头反向游以更快到达起点,HtBest想让你求出小鲲最少比HtBest提前多长时间完成比赛。(若HtBest比小鲲先完成比赛,输出负数)

    说明:小鲲不会作弊。

输入:
一行,包含四个正整数,两两之间用空格分开:L(游泳池周长)、k(互相监督距离)、a(小鲲速度)、b(HtBest速度)。
所有输入数据均不超过1e9。

输出:

一行,包含一个数,表示小鲲最少比HtBest提前多长时间完成比赛。(保留两位小数)。

样例输入:

4 3 2 1

样例输出:

2.00

样例输入:

10 2 3 1

样例输出:

-1.33

题意:

有一个人H和一个鲲同时从同一起点沿着一个圆环游动,当两个人的距离小于K的时候,处于互相监督,H只能继续以最大速度向前游,当两个人距离大于等于K时,H就可以作弊,他可往回游,也可以继续向前游,但是无论何时鲲都不会作弊,告诉你圆环的周长,两人距离K,以及H和鲲的速度,求鲲最少比H先到多少时间,如果H先到输出负数。

思路:

主要是判断在鲲未到达终点时,H与鲲的距离能不能产生K,模拟一下就可以了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#define INF 0x3f3f3f3f
#define ONF 0xc0c0c0c0
using namespace std;
typedef long long LL;
LL c,k,x,y,f,h,g,mark,h1;
double a,b;
void init()
{
    b=c*1.0/y;
    a=c*1.0/x;
    printf("%.2lf
",b-a);
}
int main()
{
    while(scanf("%lld %lld %lld %lld",&c,&k,&x,&y)!=EOF)
    {
        mark=0,g=0;
        if(y>x)              //特判,当H的速度大于鲲的速度,直接计算。
        {
            init();
            continue;
        }
        for(int i=1;;i++)
        {
            LL l=i*x;
            LL r=i*y;
            LL s=l-r;
            if(l>=c)
                s=c-r;           //当鲲游过周长时,鲲就停留在0点处,此时鲲和H的距离就是周长减去H走过的距离。
            if(s>=k)             //如果距离大于等于K,记录下鲲和H此时的位置和经过的时间,标记g=1。
            {
                g=1;f=i;h=r;h1=l;break;
            }
            if(l>=c) break;      //如果鲲和H的距离失踪小于K,那么添加跳出循环的条件
        }
        if(g==1)
        {
            if(h<=(c*1.0)/2)     //如果H处在小于半周长的位置,那么考虑往回走。
            {
                while(1)
                {
                    h=h-y;h1=h1+x;
                    if((c-h1+h<k)||(h>0&&h1>=c))  //如果在H往起点靠近的时候,鲲也往起点靠近的时候,两个的距离小于K,那么H依旧只能走完一周。
                    {
                        mark=1;   //或者鲲到了起点而H还没到,那么H也只有走完一周。
                        break;
                    }
                    if((c-h1+h>=k)&&h<=0&&h1<c)  //如果H到达起点而鲲还没到并且鲲和H之间的距离依旧是大于等于K的,那么直接跳出循环。
                    break;
                }
                if(mark==1)   //如果mark等于1,那么H要游完一周。
                {
                    init();
                    continue;
                }
                else  //如果mark等于0,那么H直接可以反向游回去
                {
                    b=f*2.0;
                    a=c*1.0/x;
                    printf("%.2lf
",b-a);
                    continue;
                }
            }
            else  // 当H超过半周长的一半时,也只有游完一周。
            init();
        }
        else  //如果H和鲲的距离一直是小于K的,那么H也只有游完一周。
        init();
    }
}

注意点:

在H往回走靠近终点的时候,鲲也在靠近终点,此时如果两个的距离小于K了,那么H就不能直接回到终点了,还是需要游完一圈。

原文地址:https://www.cnblogs.com/Leozi/p/13281240.html