[LOCAL] 过河(数学) | 错题本

21 篇文章 0 订阅
14 篇文章 0 订阅

文章目录

题目

一只青蛙想从河的一侧跳到另一侧。河中有一些石子,青蛙必须要经过这些石子才能够顺利过河。
由于青蛙一次跳过的距离是总是正整数,我们可以把河中青蛙可能到达的点看成数轴上的一串整点: 0 , 1 , ⋯   , L 0,1,\cdots,L 0,1,,L(其中 L L L 是河的宽度)。当青蛙的坐标大于 L L L 或者小于 0 0 0 时,我们就认为青蛙跳出了这条河。一旦青蛙跳出这条河,青蛙就不会选择回到河中。注意青蛙不一定最后要跳到河的另一侧。
现在,青蛙将会从 0 0 0 坐标开始,每次可以随意选择向正方向跳跃 a a a 步或者向负方向跳跃 b b b 步。
为了保障青蛙在河上的安全,你必须将所有青蛙可能跳到的坐标都铺上石子。
求使用的石子数量最少为多少?( L ≤ 1 0 12 , a , b ≤ 1 0 5 L \leq 10^{12}, a, b \leq 10^5 L1012,a,b105

分析

如果不考虑河长的限制,答案就是 ⌊ L gcd ⁡ ( a , b ) ⌋ \left\lfloor\frac{L}{\gcd(a, b)}\right\rfloor gcd(a,b)L,考虑前 L − ( a + b ) L - (a + b) L(a+b) 的部分显然是可以用上面的结论的,因为超出一个 a a a 或者 b b b 就能立刻再跳回来,然后最后的 a + b a + b a+b 格暴力即可。

代码

#include <bits/stdc++.h>

typedef long long LL;

const int MAXN = 100000;

LL L; int A, B;

inline int Gcd(const int &x, const int &y) {
	return y ? Gcd(y, x % y) : x;
}

int Ans;
bool F[2 * MAXN + 5];

void Dfs(const int &u, const int &lim) {
	F[u] = true, Ans++;
	if (u + A <= lim && !F[u + A]) Dfs(u + A, lim);
	if (u - B >= 0 && !F[u - B]) Dfs(u - B, lim);
}

int main() {
	scanf("%lld%d%d", &L, &A, &B);
	if (A + B >= L) {
		Dfs(0, L);
		printf("%d", Ans);
	}
	else {
		Dfs(0, A + B);
		printf("%lld", (L - A - B) / Gcd(A, B) + Ans);
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值