从一个有规律的数列中找被3整除的数

题目描述
小Q得到一个神奇的数列:
1, 12, 123,…12345678910,1234567891011…。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
输入描述:
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。
算法分析
我们可以从数列中看到,这些数的排列是有规律的,每个数字是一个等差数列,求每个数字的和也很简单。可以用公式n*(n+1) /2 来计算。
接下来分析什么样的数可以被3整除:
每个数字的每位总和能整除3,则这个数可以被3整除。
代码1–注意溢出

#include <iostream>
using namespace std; 
int main()
{

    long long l,r;  //l,r表示从第l个数到第r个数
    while(cin>>l>>r)
    {
        long long sum=0;
        for(long long i=l;i<=r;i++)
        {
           //第i个数的每位总和为(i+1)*i/2
            if(((i+1)*i/2)%3==0) //从第l个数到第r个数之间的能被3整除的个数
            {
                sum++;
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}

代码2–公式

#include<iostream>
using namespace std;
int main(){
    int num_1, num_2;
    cin >> num_1;  //读入第一个数
    cin >> num_2;  //读入第二个数
    --num_1;   
    --num_2;
    //对于一个数num_N+1,其能3整除的数的个数的更新公式为(num_N / 3 * 2 + num_N % 3)
    cout << (num_2 / 3 * 2 + num_2 % 3) - ((num_1 - 1) / 3 * 2 + (num_1 - 1) % 3);
    system("pause");
    return 0;
}

补充–规律

1.个位数是偶数(0,2,4,6,8)的数能被2整除;
2.个位数是0或5的数能被5整除;
3.末两位数能被4(或25)整除的数能被4(或25)整除;
4.末三位数能被8(或125)整除的数能被8(或125)整除;
5.能被6整除的数只需满足能被2,3整除.
6.各位数字之和能被3(或9)整除的数能被3(或9)整除;
7.奇数位数字之和与偶数位数字之和的差能被11整除的数能被11整除;
8.末三位数字所表示的数与末三位以前的数字所表示的数的差(大数减小数) 能被7(或11或13)整除的数能被7(或11或13)整除

猜你喜欢

转载自blog.csdn.net/qq_37954088/article/details/81707075