[牛客网刷题]被3整除

题目地址:https://www.nowcoder.com/practice/51dcb4eef6004f6f8f44d927463ad5e8?tpId=98&tqId=32825&qru=/ta/2019test/question-ranking

题目描述
小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整除。其实这样复杂度会很高。所以我们可以考虑查找这里面是不是存在一些规律。
先从最小的看起。
1%3=1;
12%3=0;
123%3=0;
1234%3=1;
12345%3=0;
123456%3=0;
1234567%3=1;
12345678%3=0;
123456789%3=0;
……
……

通过以上的打表,我们可以看到,从1开始,往后数列的每个数字对3求模都是三个里面出现两个可以整除的。那么我们可以从中总结规律:数列里面能够被3整除的数为 2*x/3。我们只需要求出左端点以左存在多少个可被3整除的数字,再求出右端点以左有多少个可被3整除的数字,然后用后者的个数减去前者即可。

故而,我们有以下代码:

#include <bits/stdc++.h> 
using namespace std;

int check(int x){
    return 2*x/3;
}

int main(){
    int l,r;
    scanf("%d%d",&l,&r);
    cout<<check(r)-check(l-1)<<endl;
    return 0;
}

Piece of cake.

你好啊,谢谢你来看我。
原文地址:https://www.cnblogs.com/sitr/p/13034548.html