题目描述
小Q得到一个神奇的数列: 1, 12, 123,…12345678910,1234567891011…。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
输入描述:
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。
示例1
输入
2 5
输出
3
说明
12, 123, 1234, 12345...
其中12, 123, 12345能被3整除。
思路
一个数能否被3整除,可以通过把每一位的数相加和是否为3的倍数判断。
如:12=====>1 + 2 = 3 是3的倍数,所以12可以被3整除。
对于 小Q的神奇数列,当取正整数n时,12…n是否可能被3整除等价于1到n求和是否能被3整除。
a
n
=
∑
i
=
0
n
i
=
n
(
n
+
1
)
2
a_n = \sum_{i=0}^{n}i=\frac{n(n+1)}{2}
an=i=0∑ni=2n(n+1)
当n可以被3整除或者n+1可以被3整除的时候,这个神奇数可以被三整除。
所以,连续的3个正整数中必然会有2个符合条件,可以进一步简化为:
l与r之间有d = r-l+1个数中,有 d / 3 * 2个符合条件,剩余的re = d%3个数需要单独判断是否满足re可以被3整除或者re+1可以被3整除。
代码
#include <stdio.h>
bool isTriple(unsigned int num) {
if (num % 3 == 0 || (num + 1) % 3 == 0) {
return true;
}
return false;
}
int main()
{
unsigned int l = 0, r = 0, sum = 0;
scanf("%u %u", &l, &r);
unsigned int diff = r - l + 1;
unsigned int n = diff / 3;
unsigned int remain = diff % 3;
for (unsigned int i = l; i < l + remain; ++i) {
if (isTriple(i)) {
++sum;
}
}
sum += 2 * n;
printf("%d", sum);
return 0;
}