时间限制:1秒
空间限制:32768K
小Q得到一个神奇的数列: 1, 12, 123,…12345678910,1234567891011…。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
输入描述:
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。
输入例子1:
2 5
输出例子1:
3
例子说明1:
12, 123, 1234, 12345…
其中12, 123, 12345能被3整除。
开始直接用数位之和来求,只通过70%。冥冥之中觉得这其实是一道找规律的题目
开了解答,果然是。
其实规律很简单,余数是有规律的:100100100100100100….
也就是每三个数有两个
代码如下
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int begin = scanner.nextInt();
int end = scanner.nextInt();
System.out.println(helper(end) - helper(begin - 1));
}
public static int helper(int num){
return (num / 3) * 2 + ((num % 3) > 0 ? (num%3) - 1 : 0);
}
下面是网上高手对这种规律的证明,其实发现规律后,白想想也能看出规律的正确与否,这个题给我一个教训,要多尝试
链接:https://www.nowcoder.com/questionTerminal/51dcb4eef6004f6f8f44d927463ad5e8?toCommentId=1235333
来源:牛客网
记插入数字i以后形成的新数字为a[i],数字a[i]的余数记作last[i]
容易发现,a[i] = a[i-1]*10k + i。
则
last[i] = a[i]%3 = (a[i-1]*10k + i)%3
= (a[i-1]*(10k -1) + (a[i-1] + i))%3
=(a[i-1] + i)%3
=(a[i-1]%3 + i%3)%3
=(last[i-1] + i%3)%3
则last满足递推关系:
last[i] = (last[i-1] + i%3)%3
数学归纳法:
当k = 0的时候:
last[0] = 0、last[1] = 1、last[2] = 0成立
假设规律last[3k+1] = 1、last[3k] = 0、last[3k+2] = 0成立;
则对于任意k+1而言
last[3(k+1)] = last[(3k+2) + 1] = (0 + 3(k+1)%3)%3 = 0
last[3(k+1)+1] = (0 + (3(k+1)+1)%3)%3 = 1
last[3(k+1)+2] = (1 + (3(k+1)+2)%3)%3 = (1+2)%3 = 0
可见对任意k,上述规律恒成立。
综上,last[i] = i%3==1