喵~ 各位算法大师和未来的大师们,你们好呀!我是你们的小助教猫娘,今天也要元气满满地和大家一起学习算法哦!今天要拆解的题目是 Codeforces 上的一个可爱问题——失眠的公主殿下和可怜的龙龙们。
那么,就让我们开始吧!
A. Insomnia cure (失眠治疗)
题目大意
有一位睡不着觉的公主殿下喵~ 她不数羊啦,觉得太幼稚了,所以开始数龙!但是光数数也很无聊,于是她开始在脑内和这些想象中的龙龙们战斗。
规则是这样的:
- 每第 k 只龙,都会被公主用平底锅狠狠地敲脸。
- 每第 l 只龙,尾巴会被阳台门夹到。
- 每第 m 只龙,爪子会被公主的高跟鞋踩扁。
- 每第 n 只龙,会被公主威胁说要叫妈妈,然后吓得落荒而逃。
现在公主殿下总共数了 d 只龙。我们需要计算一下,从第1只到第d只,总共有多少只龙遭受了(精神或物理上的)伤害呢?
输入是 k, l, m, n, d
这五个整数,我们需要输出一个整数,代表受伤龙龙的总数。
举个例子喵: 如果 k=2, l=3, m=4, n=5, d=24
。 那么第2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24号龙龙都会受伤。总共是17只。注意哦,像第6号龙龙,它既是2的倍数也是3的倍数,受到了双重打击,但我们只记为1只受伤的龙。
题解方法
这个问题呀,最直接的方法就是... 喵~ 就是我们真的去当一次公主殿下,把从第1只到第d只龙龙全部检查一遍!
这个方法叫做模拟 (Simulation)。因为题目给出的龙的总数 d
最大只有 100,000
,这个数字对于计算机来说简直是小菜一碟,一瞬间就能处理完。所以我们完全不需要去想什么复杂的数学公式(比如容斥原理什么的,对这个问题来说有点杀鸡用牛刀啦)。
我们的思路是这样的:
- 准备一个计数器
count
,初始化为0,用来记录受伤龙龙的数量。 - 写一个循环,从
i = 1
开始,一直到i = d
结束。这个i
就代表当前正在检查的龙的编号。 - 在循环里面,我们检查当前的龙
i
是否需要被“修理”。只要满足下面任何一个条件,它就是一只受伤的龙:i
是k
的倍数 (i % k == 0
)i
是l
的倍数 (i % l == 0
)i
是m
的倍数 (i % m == 0
)i
是n
的倍数 (i % n == 0
)
- 如果满足了至少一个条件,我们就把计数器
count
加一。 - 循环结束后,
count
里的数字就是我们想要的答案啦!
这个方法非常直观,也很好写,最适合我们这些可爱的初学者了喵~
题解 (C++ 代码)
下面是具体的实现代码,猫娘已经帮大家加上了可爱的中文注释哦!
#include <iostream>
/**
* 喵~ 这是解决 Codeforces 148A "Insomnia cure" 问题的代码。
* 题目要求我们计算在 d 只龙中,有多少只受到了伤害。
* 如果一只龙的编号是 k, l, m, n中任意一个数的倍数,它就算受伤了。
*
* 我们用的方法是直接模拟!遍历从 1 到 d 的每一只龙,
* 检查它是否满足受伤的条件。
*
* 约束条件:
* 1 <= k, l, m, n <= 10
* 1 <= d <= 10^5
*
* d 的最大值是 100,000,所以一个简单的 O(d) 复杂度的循环是完全足够快的,
* 能在时间限制内轻松通过。这个方法简单易懂,也避免了使用复杂的容斥原理。
*/
int main() {
// 这两行是为了让输入输出更快一点,打比赛的时候很有用哦~
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
// 定义公主殿下给出的几个数字喵~
// k, l, m, n: 伤害龙的周期
// d: 龙的总数
int k, l, m, n, d;
// 把这五个数字读进来啦
std::cin >> k;
std::cin >> l;
std::cin >> m;
std::cin >> n;
std::cin >> d;
// 这是我们的小本本,用来记下受伤龙龙的数量,初始是0哦
int damaged_count = 0;
// 开始从第1只龙龙数到第d只~
for (int i = 1; i <= d; ++i) {
// 检查这只龙龙的编号 i 是不是 k, l, m, n 中任何一个的倍数。
// 我们用取模运算符 '%' 来检查整除。
// '||' 是逻辑或,表示只要有一个条件成立,整个判断就为真。
// 一只龙就算被多种方式伤害,也只算一次啦。
if (i % k == 0 || i % l == 0 || i % m == 0 || i % n == 0) {
// 如果是的话,就在小本本上+1!
damaged_count++;
}
}
// 最后,告诉大家我们数出来有多少只龙龙受伤啦
std::cout << damaged_count << std::endl;
// 程序顺利结束,返回0~
return 0;
}
知识点介绍
这道题虽然简单,但里面包含了一些非常基础和重要的编程知识点,我们来一起复习一下吧,喵~
循环结构 (for loop) 就像我们猫咪每天都要巡视自己的领地一样,
for
循环可以让我们重复执行一段代码。在这里,for (int i = 1; i <= d; ++i)
就是让我们的程序把第1只到第d只龙挨个检查一遍,一只都不能少!条件判断 (if statement)
if
语句就像是我们的判断力。看到一个箱子,我们会判断“能钻进去吗?”。程序也是一样,if (...)
括号里的条件如果为真,就执行后面的代码块。这里我们用它来判断龙龙是否受伤。取模运算符 (
%
) 这个%
符号超有用的说!a % b
计算的是a
除以b
得到的余数。所以,i % k == 0
的意思就是i
除以k
的余数是0,换句话说,i
可以被k
整除,也就是i
是k
的倍数啦。是不是很简单喵?逻辑或运算符 (
||
) 两条竖线||
就像在说“或者”。条件A || 条件B
的意思是,只要条件A和条件B里至少有一个是真的,那么整个表达式就是真的。在我们的代码里,只要龙的编号是k
或l
或m
或n
中任何一个的倍数,它就要倒霉了。
好啦,今天的解题分享就到这里啦!是不是感觉很简单,也很有趣呢?通过模拟公主殿下的行为,我们轻松地解决了问题。希望大家都能从中学到东西,下次遇到类似的题目也能一爪子拍死!喵~
如果还有什么问题,随时可以再来找猫娘哦!我们下次再见!