[编程题] 被3整除

【问题】:

小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。

并且小Q对于能否被3整除这个性质很感兴趣。

小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。

输入描述:

输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。

输出描述:

输出一个整数, 表示区间内能被3整除的数字个数。

输入例子1:

2 5

输出例子1:

3

例子说明1:

12, 123, 1234, 12345...
其中12, 123, 12345能被3整除。

【解决】:

【规律】

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)整除

【注意】当数字大于10,需要加上每个个位数。

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int l = sc.nextInt();
        int r = sc.nextInt();
        int sum = 0;
        for (int i = 1;i < l;i ++){
            int tmp = i;
            while(tmp != 0){
                sum += tmp % 10;
                tmp /= 10;
            }
        }
        int count = 0;
        for (int i = l;i <= r;i ++){
            int tmp = i;
            while(tmp != 0){
                sum += tmp % 10;
                tmp /= 10;
            }
            if (sum % 3 == 0){
                count ++;
            }
        }
        System.out.println(count);
    }
}

超时了,循环过多!!!

-------------------------------------------------------------------------------------------------------------

折腾了半天,发现,只要把所有的类型变为long就可以。。。。

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long l = sc.nextInt();
        long r = sc.nextInt();

        long sum = 0;
        for (long i = 1;i < l;i ++){
            sum += i;
        }
        long count = 0;
        for (long i = l;i <= r;i ++){
            sum += i;
            if (sum % 3 == 0){
                count ++;
            }
        }
        System.out.println(count);
    }
}

-------------------------------------------------------------------------------------------------------------

 ② 找规律:

当插入i以后有如下规律:

i = 1 ---- 1----> 1

i = 2 ---- 12----> 0

i = 3 ---- 123----> 0

i = 4 ---- 1234 ---->1

i = 5 ---- 12345 ---->0

i = 6 ---- 123456 ---->0

i = 7 ---- 1234567 ----> 1

可以看到,在区间[1,x]之间共计有 f(x) = (x+2)/3 个1,剩下的都满足要求

那么在区间[l, r]上的 r-l+1个 数字中,必须抠掉 f(r) - f(l-1) 个不满足要求的数字。

直接打印出来就可以了,O(1),不需要循环遍历。

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int l = sc.nextInt();
        int r = sc.nextInt();
        int count = r - l + 1 - (f(r) - f(l - 1));
        System.out.println(count);
    }
    public static int f(int x){
        return (x + 2) / 3;
    }
}

猜你喜欢

转载自my.oschina.net/liyurong/blog/1786363