网易笔试编程题 被3整除

时间限制: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)%3last满足递推关系:
last[i] = (last[i-1] + i%3)%3
数学归纳法:
当k = 0的时候:
last[0] = 0last[1] = 1last[2] = 0成立

假设规律last[3k+1] = 1last[3k] = 0last[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

猜你喜欢

转载自blog.csdn.net/ymybxx/article/details/79991293
今日推荐