题目:
一个数列: 1, 12, 123, 1234, 12345,...12345678910,1234567891011...。计算从数列的第 m 个到第 n 个(包含端点)有多少个数可以被3整除。
方法一:
for循环m 到 n ,循环内内嵌一个循环,算出当前的数字是多少,是否能被3整除,能则计数+1,不能计数不加1。
这是最容易想到的办法,就不写出来了。
方法二:
改进一下方法一,for循环m 到 n ,循环内内嵌一个循环,计算出当前数字每位之和,判断是否能被3整除,能则计数加1,不能就不加1。
function findNum1(m,n){
let nums=0;
for(var i=m;i<=n;i++){
var num=1;
for(var j=2;j<=i;j++){
num=num+j;
}
if(num%3==0){
nums++;
}
}
console.log(nums)
}
方法三:
改进方法二,for循环m 到 n ,计算当前数字每位之和,判断是否能被3整除,发现当前数字每位之和有规律:
i | 当前数字 | 每位之和 |
1 | 1 | 1 |
2 | 12 | 3 |
3 | 123 | 6 |
4 | 1234 | 10 |
... | ... | ... |
i | 1234...i | (1+i)*i/2 |
相比方法二减少一层循环。
function findNum2(l,r){
let nums=0;
for(var i=l;i<=r;i++){
var num=((i+1)*i)/2;
if(num%3==0){
nums++;
}
}
console.log(nums)
}
方法四:(这个真没想到,记录一下别人的棒方法!)
i | 数字 | 是否能被3整除 |
1 | 1 | F |
2 | 12 | T |
3 | 123 | T |
4 | 1234 | F |
5 | 12345 | T |
6 | 123456 | T |
7 | 1234567 | F |
8 | 12345678 | T |
9 | 123456789 | T |
规律:从1开始,每3个数字中有1个不能被3整除,所以数列1~m中,有 parseInt( (m+2)/3 ) 个不能被3整除,剩下的m - parseInt( (m+2)/3 ) 个可以被3整除;则数列m~n中,有m - n + 1 个数字,其中有 parseInt( (n+2)/3 ) - parseInt( (m-1+2)/3 ) 个不能被3整除,剩下的 m - n + 1 - ( parseInt( (n+2)/3 ) - parseInt( (m-1+2)/3 ) )个数字是可以被3整除的。规律也是可以证明的,这里(略~)
这样就不用循环了。
function findNum3(m,n){
let nums = n - m + 1 - ( parseInt((n+2)/3) - parseInt((m+1)/3) );
console.log(nums)
}