Codeforces Round#328 div.2 C

题意:

有两个机器人,走路的速度是一样的,一个机器人一步走w米,一个机器人一步走b米,现在给出的赛道长最大为t,问在这些长度中,选择哪些长度会导致平局。需要注意的是,如果此时机器人的下一步将会超过剩余赛道长度,那么机器人就不会走这一步。而所谓胜局的情况是在没有平局的情况下,谁离起点最远谁就是赢家。

思路:

首先这道题千万不要被速度给搞晕了,即使速度一样,那么频率也有可能不一样。这时候直接看步数,我们可以很快的找出来当长度为他们的最小公倍数时到达同一位置,还有一种情况就是当长度小于他们中的最小值,那么肯定是平局的。所以长度t可以分成n个lcm块,对于每一个LCM块里面,长度比min(w,b)最小还小的值一定是属于平局的情况,还有每一块的最后一个值,即为w,b的公倍数的一定也是不满足情况的。

讨论要分情况:

当LCM>t时:

这时候t已经是属于块中了,所以直接找到min(t,w-1,b-1)就行了。但是,测试数据绝对都是特别大的数据,单纯的算LCM可能会超出long long。所以直接采用取对数的方法,log(lcm)>log(t); log(lcm)=log(a)+log(b)-log(gcd(a,b));

当LCM<=t时:

此时就可以把长度t进行分块,每一个块的长度是LCM,但是还有情况:即有可能t无法整除LCM,那么对于剩下来的那一部分,如果剩下来的那部分长度是大于min(w,b)的,那么直接把最后剩下的那段长度只取min(w-1,b-1);

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
LL t,w,b;
LL gcd(LL a,LL b)
{
	if(b==0)
		return a;
	return gcd(b,a%b); 
}
LL LCM(LL a,LL b)
{
	return a/gcd(a,b)*b;
}
bool issmall(LL a,LL b,LL t)
{
	if(log(a*1.0)+log(b*1.0)-log(gcd(a,b)*1.0)>log(t*1.0))
		return 1;
	return 0;
}
int main()
{
	cin>>t>>w>>b;
	LL ans;
	if(w==b)
	{
		ans=t;
	}
	else if(issmall(w,b,t))
	{
		ans=min(w-1,min(b-1,t));
	}
	else
	{
		LL lcm=LCM(w,b);
		LL times=t/lcm;
		if(times*lcm+min(w,b)<=t)
		{
			ans=(times+1)*min(w,b)-1;
		}
		else
		{
			ans=times*(min(w,b)-lcm)+t;
		}
	}
	cout<<ans/gcd(ans,t)<<"/"<<t/gcd(ans,t);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值