题解
纸的张数
1 条题解
-
0
解题思路
一本书第 1 页和第 2 页在同一张纸上,第 3 页和第 4 页在同一张纸上,第 5 页和第 6 页在同一张纸上……也就是每张纸上有相邻的两页。大白老师从第 x 页看到第 y 页,问一共用了几张纸。
第一步:搞清楚"第 p 页在第几张纸上"。把纸从 1 开始编号:
- 第 1、2 页 → 第 1 张纸;
- 第 3、4 页 → 第 2 张纸;
- 第 5、6 页 → 第 3 张纸;
- 第 7、8 页 → 第 4 张纸;……
找规律:第 p 页所在的纸的编号,可以用公式 (p + 1) / 2(整除)算出来: p=1 → 2/2=1;p=2 → 3/2=1;p=3 → 4/2=2;p=4 → 5/2=2。和上面列出的完全一样。
第二步:从 x 页看到 y 页,横跨了从"第 x 页所在纸"到"第 y 页所在纸"的所有纸。因为纸的编号是一张接一张的,所以纸的张数 = 第 y 页所在纸的编号 - 第 x 页所在纸的编号 + 1。
验证样例 1:x=1、y=4。第 1 页在第 1 张纸,第 4 页在第 2 张纸,张数 = 2 - 1 + 1 = 2,输出 2,正确! 验证样例说明 2:x=2、y=5。第 2 页在第 1 张纸,第 5 页在第 3 张纸,张数 = 3 - 1 + 1 = 3,正确!
为什么最后要 +1?因为"第 x 页那一张纸"自己也要算进去。比如从第 1 页看到第 4 页,包含了第 1 张纸和第 2 张纸,两头的纸都要数上。
这类"找规律再套公式"的题目,关键是先写出几行小数据,看出规律,再用整除法把规律变成公式,最后验证样例是否对得上。
参考代码
#include <iostream> using namespace std; int main() { int x, y; // 从第 x 页看到第 y 页 cin >> x >> y; // 第 p 页所在纸张编号 = (p + 1) / 2 int sx = (x + 1) / 2; // 第 x 页在第几张纸上 int sy = (y + 1) / 2; // 第 y 页在第几张纸上 // 从第 x 页那张纸到第 y 页那张纸,纸的张数 int ans = sy - sx + 1; // 两头都算,所以要 + 1 cout << ans << endl; // 输出纸的张数 return 0; }复杂度分析
只读入 2 个数,做几次加法和除法,运算次数固定,和 x、y 的大小(最大 100000)无关。时间复杂度和空间复杂度都是 O(1)。
- 1