題目:
一個數列: 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)
}