时间限制 | 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就不能直接回到终点了,还是需要游完一圈。