【题目描述】
小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)整除