图书馆里有 (n) 本书,混入了一只老鼠。老鼠每 (x) 小时可以啃光一本书,并且在啃光一本书之前不会去啃另一本。也就是说,老鼠会一本一本地按顺序啃书。经过 (Y) 小时后,问图书馆里还剩下多少本完整的书。
输入保证 (Y) 小时后至少会剩下一本完整的书。数据范围 (1 \leq n, x, y \leq 1000),非常小,但我们可以用数学方法直接 (O(1)) 计算出结果。
关键在于理解“完整书”和“被啃过的书”的区别:
因此,(Y) 小时后,图书馆里不完整的书可以分为两部分:
用公式表示:
[
\text{被啃过的书} = \lfloor Y / x \rfloor + \begin{cases} 1, & Y \bmod x \neq 0 \ 0, & Y \bmod x = 0 \end{cases}
]
由于老鼠不会同时啃多本书,这个计算方式是准确的。
最后,完整的书数量 = 总数 (n) − 被啃过的书数量。
finished = y / x(整数除法自动向下取整)。y % x > 0,则 current = 1,否则 current = 0。damaged = finished + current。remaining = n - damaged。remaining。示例演示(与参考代码逻辑一致):
n = 10, x = 3, y = 7finished = 7 / 3 = 2(第13小时啃完第1本,第46小时啃完第2本)current = (7 % 3 > 0) -> 1(第7小时正在啃第3本)damaged = 2 + 1 = 3remaining = 10 - 3 = 77算法只进行常数次的算术运算和逻辑判断,不涉及循环或递归,因此时间复杂度为 (O(1)),空间复杂度也为 (O(1))。对于 (n, x, y \leq 1000) 的数据完全可以瞬间完成。
cpp1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 int n, x, y; 6 cin >> n >> x >> y; 7 8 // 老鼠在y小时内已经啃完的书的数量 9 int finished_books = y / x; 10 // 老鼠正在啃的书(如果有的话) 11 int current_book = (y % x > 0) ? 1 : 0; 12 13 // 被啃过的书 = 已啃完的 + 正在啃的 14 int damaged_books = finished_books + current_book; 15 16 // 剩余完整书 = 总数 - 被啃过的 17 int remaining = n - damaged_books; 18 19 cout << remaining << endl; 20 21 return 0; 22}
代码说明:
y / x:C++ 中整数除法会舍去小数部分,正好得到“完全啃完”的本数。y % x > 0:如果余数大于 0,说明这 y 小时内除了啃完 y/x 本外,还有一段时间正在啃下一本。? 1 : 0 用于决定是否把当前正在啃的书计入不完整书籍。注意事项:
y 小时后至少有一本完整的书,因此 remaining >= 1,不需要额外的边界处理。这道题考察了简单的整除和取模运算,以及将实际问题转化为数学公式的能力。只要弄清楚老鼠啃书的顺序,就能轻松解决。