首页 > 试题广场 >

被3整除

[编程题]被3整除
  • 热度指数:138977 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

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

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

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


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


输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。
示例1

输入

2 5

输出

3

说明

12, 123, 1234, 12345...
其中12, 123, 12345能被3整除。
package com.shengxi.niuke;


import java.util.Scanner;

public class Day006 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);


        int l = scan.nextInt();
        int r = scan.nextInt();
        int cnt = 0;
        for(int i=l;i<=r;i++) {
            if(i%3!=1) {
                cnt++;
            }
        }
        System.out.println(cnt);
    }


}


根据数论中的整除,可以用另外一个方案得到结果
编辑于 2020-06-01 22:37:29 回复(1)
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int l = in.nextInt();
            int r = in.nextInt();
            if(r<l){
                throw new RuntimeException();
            }
            int count = 0;
            for(int i = l; i<=r; i++){
                long num = getNum((long)i);
                if(num % 3 == 0){
                    count++;
                }
            }
            System.out.println(count);
            
        }
    }
    
    private static long getNum(long num){
        String str = "";
        for(int i = 1; i<=num; i++){
            str = str+i;
        }
        long res = Integer.valueOf(str);
        return res;
    }
}

发表于 2020-04-06 10:02:14 回复(0)

不太懂题的意思,我以为直接求两个数中可以整除3的个数和。写出来也通过了。看评论区发现自己想的有些简单

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
/**
left right 边界 里面能整除3的个数,只需要对边界值判断即可。
如果 left 可以整除3
   说明左边界包括一个 。 只需要right包括的3的个数 - left 包括的 + 1
如果左边界不是
     上式不用 + 1即可。
*/
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int l = sc.nextInt();
            int r = sc.nextInt();
            System.out.println(l % 3 == 0 ? r / 3 - l / 3 + 1 : r / 3 - l / 3);
        }
    }
}
发表于 2020-02-14 23:54:10 回复(0)

找到这个数列的规律就可以了,就是1,2,3,4,5,6,7,8,9,10,11,12,13,14……字符串拼接,第几个数就拼接几次

import java.util.*;

public class Main
{
    public static void main(String [] args)
    {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNextInt())
        {
            int a=sc.nextInt();
            int b=sc.nextInt();
            System.out.println(getResult(a,b));
        }

    }

    public static int getResult(int a,int b)
        {
            int count=0;//计数器
            for(int i=a;i<=b;i++)
            {
                if(getNum(i)%3==0)
                {
                    count++;
                }
            }
            return count;          
        }

        public static long getNum(int index)
        {
            StringBuilder sb=new StringBuilder();
            for(int i=1;i<=index;i++)
            {
                sb.append(""+i);
            }
            String str=sb.toString();
            long num=Long.parseLong(str);
            return num;
        }
}
发表于 2020-02-12 19:37:56 回复(0)
//这道题在提交的时候 系统让我测试 10 ~ 110   到110  这得是多长的数据啊? 怎么做求余,long类型都
//存不下
public class Main{
public static void main(String[] args){
            int count = 0;
            int l = 10,r = 110;
            long[] arr=nums(r);
            for(int i =l ;i<=r;i++){
                if(arr[i-1] % 3 == 0) count++;
            }
            System.out.println(count);
        }
        //生成队列 返回long[11]
        public static long[] nums(int count){
            long[] arr = new long[count];
            StringBuffer sb = new StringBuffer();
            for(int i = 1;i<=arr.length;i++){
                sb.append(i);
                arr[i-1]=Long.parseLong(sb.toString());
            }
            return arr;
        }
}
发表于 2019-11-29 19:45:41 回复(0)
简单易懂的一种解法,仅供参考(大神请略过此条评论)
public class Main{
    public static void main(String args[]){
        fun(2,5);
    }
    public static int fun(int l,int r){
        int count=0;
        int temp=0;
        StringBuffer sbl=new StringBuffer("");
        StringBuffer sbr=new StringBuffer("");
        for(int i=l;i<=r;i++){
            for(int j=1;j<=l;j++){
                sbr=sbl;
                sbr.append(i);
                temp=Integer.parseInt(sbl.toString());
                if(temp%3==0){
                    count++;
                }
            }
        }
        return count;
    }
}
发表于 2019-11-17 14:29:31 回复(0)
import java.util.Scanner;
// import java.math.BigInteger;

public class Main {
	public static void main(String[] args) {
		// 据观察,序列满足×√√×√√×√√×√√...
        // 该题right并不超过int类型,2^31 - 1 > 2*10^9
        // 如果超过整型范围,用BigInteger来计算
		Scanner scan = new Scanner(System.in); 
		int left = scan.nextInt();
		int right = scan.nextInt();
		if(left == 1)
			System.out.print(getNumbers(right));
		else
			System.out.print(getNumbers(right) - getNumbers(left - 1));
		scan.close();
	}

	public static int getNumbers(int x) {
        // 也就是求getNumbers(1, right) - getNumbers(1, left)
		return ((x/3) << 1) + (x % 3 > 1 ? 1 : 0);
	}
//	static BigInteger two =new BigInteger("2");
//	static BigInteger three =new BigInteger("3");
//	public static void main(String[] args) {
//		Scanner scan = new Scanner(System.in); 
//		BigInteger left = scan.nextBigInteger();
//		BigInteger right = scan.nextBigInteger();
//		if(left.compareTo(BigInteger.ONE) == 0 )
//			System.out.print(getNumbers(right));
//		else
//			System.out.print(getNumbers(right).subtract(getNumbers(left.subtract((BigInteger.ONE)))));
//		scan.close();
//	}
//
//	public static BigInteger getNumbers(BigInteger x) {
//        // 也就是求getNumbers(1, right) - getNumbers(1, left)
//		return ((x.divide(three)).multiply(two)).add(new BigInteger(String.valueOf((x.mod(three)).compareTo(BigInteger.ONE) > 0 ? 1 : 0)));
//	}
}



发表于 2019-10-02 20:55:30 回复(0)
import java.util.Scanner;
//每连续三个数中必有两个数能被三整除,先算出一共有多少组3个数
//再分别判断余下的1或2个数中有几个3的倍数
//从1开始,分布规律为 NYYNYYNYY...
//N代表不是3的倍数,Y代表是3的倍数
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        while(input.hasNext()){
            int l = input.nextInt();
            int r = input.nextInt();
            System.out.println(Solution(l, r));
        }
        input.close();        
    }
    public static int Solution(int l, int r) {
		if(l > r)
			return 0;
		else if((r + 1 - l)%3 == 0)
			return (r + 1 - l)/3 * 2;
		else if((r + 1 - l)%3 == 1)
			return (r + 1 - l)/3 * 2 + ((r%3 == 1) ? 0 : 1);
		else
			return (r + 1 - l)/3 * 2 + ((r%3 == 0) ? 2 : 1);  	
    }
}

编辑于 2019-09-16 09:52:38 回复(0)
import java.util.*;
public class Main{
    //参考一位大神的数学归纳法:在区间[1 , x]***有f(x) = (x+2)/3个不能被整除的,其余的全能被整除
    //那么区间[l , r]***有数字r-l+1个,其中存在不能整除的个数是f(r)-f(l-1)个
    //那么最后能被整除的个数就是 r-l+1-(f(r)-f(l-1))个
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int l = sc.nextInt();
        int r = sc.nextInt();
        System.out.println(r - l + 1 - (r + 2) / 3 + (l - 1 + 2) / 3);
    }
}

编辑于 2019-09-02 11:45:28 回复(1)
import java.util.Scanner;

public class Main {
	public static void main(String args[]){
		Scanner input=new Scanner(System.in);
		int l,r,count=0;
		l=input.nextInt();
		r=input.nextInt();
		int yushu=0;
		int value=0;
		StringBuffer str=new StringBuffer();
        //最左边的数是否是3的倍数
		for(int j=1;j<=l;j++){
			str.append(String.valueOf(j));
			value+=Integer.parseInt(str.substring(j-1, j));
		}
		yushu=value%3;
		if(yushu==0){
			count++;
		}
        //后面的数用前面的余数加此时最后一位数取余数判断是否是3的倍数
		for(int i=l+1;i<=r;i++){
			yushu=(i+yushu)%3;
			if(yushu==0){
				count++;
			}
		}
		System.out.println(count);
	}
}

本地可以运行,在线编译器报错:
不通过
您的代码已保存
请检查是否存在数组越界等非法访问情况
case通过率为0.00%
网上已提交的代码没用BigInteger 在本地报错 超出Integer范围
编辑于 2019-08-21 20:49:23 回复(0)
import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
    static int min =  Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int l = cin.nextInt();
        int r = cin.nextInt();
        System.out.println(r *2/3 - (l-1)*2/3);
    }
}

1-x 被3整除个数为x*2/3

发表于 2019-08-11 22:45:37 回复(0)
import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int l = sc.nextInt();
            int r = sc.nextInt();

            System.out.println(cal(r) - cal(l - 1));
        }
    }

    private static int cal(int n) {
        int sum = n / 3 * 2;
        if (n % 3 == 2)
            return sum + 1;
        else
            return sum;
    }


}
首先得找到规律,我们可以发现1,12,123这种,

每三个数中有两个能被3整除,所以我们可以把数字按成多份,每份有3个,每3个中有2个能被3整除。就是n/3*2这个式子。分完之后,再对多余部分进行分析,余数为0,那么直接返回结果,余数为1,看表格也是直接返回结果,余数为2,会多一种情况。
最后算出1到r的结果,减去1到l的结果,得到l到r的结果。
发表于 2019-08-10 21:34:48 回复(5)
先考虑第i个数字能否被3整除,可以找到规律:当i%3==1时不可被整除,其他情况均可被整除,所以只要找到从m到n这n-m+1个数字中,有多少个不可被整除的数字,用n-m+1减去这个数字就好了。找总共有多少个数字不可被整除:发现规律:当m%3==1并且(n%3==1或者n%3==2)时有(n-m+1)/3+1个,其他情况有(n-m+1)/3个。所以就很容易求得结果啦。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long m = scanner.nextInt();
        long n = scanner.nextInt();
        if ((m % 3 == 1 && n % 3 == 1)||(m % 3 == 1 && n % 3 == 2) ){
            System.out.println(n - m - (n - m + 1) / 3);
        } else {
            System.out.println(n - m + 1 - (n - m + 1) / 3);
        }
    }
}


发表于 2019-08-10 18:53:39 回复(0)
 
 for(int index = l;index<=r;index++){
     int num = 0;
     for(int i=1;i<=index;i++){//根据三的倍数的性质,如果各位相加能够整除3就是3的倍数。
         num = num+i;
     }
     System.out.println(num%3);
     //用这种方法先试着输出一下num%3的余数,可以发现从1-20分别按100100100...这种顺序
 }
因此,根据该规律,直接对需要求的数取余即可,若余数为2或者0则对应的数为3的倍数。
import java.util.Scanner;
public class Main{
    public static void main(String[] arg){
        Scanner scan = new Scanner(System.in);
        int l = scan.nextInt();
        int r = scan.nextInt();
        if(l>=r){
            System.out.println(0);//判断左右区间是否合法
        }else{
            int count = 0;
        for(int index = l;index<=r;index++){
            if(index%3==2||index%3==0)
                count++;
        }
        System.out.println(count);
        }
        
    }
}


发表于 2019-08-05 16:39:27 回复(0)
Java版解法:佛系了,提交四次,成功三次。思路主要是找规律,从1到10,除了1,4,7,10这几位加在后面除3余数为1的数不能被3整除外其他都能。(PS:我总觉得这题有些问题,不知道是系统的原因还是什么,有时候能成功有时候失败,一开始以为是l,r都是大数,需要先用String,后来一直报错【返回非零】,抱着试试的想法重写了这个简单的,结果突然成功了。有大佬有更好的写法么,欢迎交流。)
import java.util.Scanner;

public class Main  {
    public static int sum(int i){
        return i/3*2+(i%3==2?1:0);
    }
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int l = input.nextInt();
        int r = input.nextInt();
        System.out.println(sum(r) - sum(l-1));
    }
}

发表于 2019-08-04 19:18:06 回复(3)
//3个里面一定会有2个, 然后, 就看余数, 剩下, 可能有0, 1, 2三种情况
//0的话,不需要考虑, 而1和2的话, 则需要考虑了
//然后r-l+1, 这是总的个数

//而余数为1的时候, 就看余数然后除以3, 看余数为几, 就判断初始几个就好
import java.util.Scanner;
public class Main
{
    public static void main(String [] args)
    {
        Scanner sc = new Scanner(System.in);
        int left = sc.nextInt();
        int right = sc.nextInt();
        
        int sum = right - left + 1;        //计算出总量
        
        int count = sum/3;        //计算出总量
        int rem = sum%3;            
        
        int res = count * 2;
     
         while(left>0)    //因为, 我直接用left%3, 会报出界的错, 才这么处理..
            {
                left = left-3;
            }
            
        if(rem == 1)
        {
            if((left+3) != 1)
            {
                res++;
            }
        }
        
        if(rem == 2)
        {
           
           if((left+3) == 2)
            {
                res = res + 2;
            }
            else
                res++;
     
        }
        System.out.println(res);
    }
}
发表于 2019-07-23 19:21:22 回复(0)
import java.util.Scanner;
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 = (1+l)*l/2-l;
        
        int count =0;
        for(long i=l;i<=r;i++) {
            sum=sum+i;
            if(sum%3==0) {
                count++;
            }
            
        }
        System.out.println(count);
    }
}

编辑于 2019-07-17 19:42:51 回复(0)
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int start = sc.nextInt();
int end = sc.nextInt();
System.out.print(count(start,end));
}

public static int count(int start, int end){
int count = 0;
int reminder = 0;
int flag =  start % 3; // 该数列能否被3整除的规律是     x o o x o o...所以标记输入的第一个数                                           //是处在哪个位置
int gap = end - start + 1;
reminder = gap % 3;
count = gap / 3 * 2 ;   //每3个数中必有两个能被2整除
if (( reminder == 1 && flag !=1) || (reminder == 2 && flag != 2))  //判断剩余的数(可能的个                                               //数为0个,1个,2个)中能有几个被3整出
return count+1;    //余数为1个且这个数不处于数列中 x o o 的 x 位置,或者 余数为2个
                               //且这个数不处于 x o o 中的第一个 o 上, 则剩下的数中有1个能被3整除
else if(reminder == 2)
return count+2;    //余数为2个,且这两个数对应为位置为 x o o 中的 o o,则剩下的2个数都能                                                                                                                     //被3整除
else
return count;   //余数为0个或者余数为1个且这个数正好处于 x o o 中的 x 位置,                                                               //则直接返回count

}
}
编辑于 2019-07-11 20:46:25 回复(0)
import java.util.*;
public class Main{
public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        //起始位置
        int l=in.nextInt();
        //结束位置
        int r=in.nextInt();
        //1 0 0 1 0 0 ....
        int sum=0;
        if(l>=1 && l<=r && r<=1e9){
            //根据规律进行判断,当l处于1 0 0中1号位与三号位时情况相同
            if (l%3==1 || l%3==0){
                sum=(r-l)-((r-l)/3);
            }
            //处于二号位时需要进行特殊的运算
            if (l%3==2){
                if (r-l==1){
                    sum=2;
                }else{
                    sum=(r-l)-((r-l-2)/3);
                }
            }
            System.out.println(sum);
        }else{
            System.out.println("输入错误");
        }

    }
}

//无需循环,只要找到相应规律即可

发表于 2019-07-07 23:43:48 回复(0)