第一种方法:


遍历1到sqrt(num),如果num能被循环的i整除,则当前数为num的约数,其背面num/i也为num的约数

当num为一个平方数时,i会计入两次,所以添加一个a/i!=i来判段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.HashSet;
import java.util.Set;
 
public class Main{
    static Set set=new HashSet<>();
    public static void main(String[] args) {
    //这里举例求2000的约数
        int a=2000;
        //遍历1到sqrt(2000)
        for(int i=1;i*i<=a;i++) {
            if(a%i==0) {
            //加入集合
                set.add(i);
                //判段是否为i*i=num,排掉重复
                if(a/i!=i) {
                    set.add(a/i);
                }
            }
        }
        //输出约数
        for(int i:set) {
            System.out.println(i);
        }
        System.out.println();
        //输出约数个数
        System.out.println(set.size());
    }
     
}

第二种方法:

其实第二种方法我用的还比较多,从蓝桥杯20年国赛第三题用的就是这种方法好算一些,但是这个方法好像在这道题时间会溢出,麻了。

    第一步:欧拉筛选质数

    第二部:判段传入num是否为质数,如果为质数,则直接返回2,如果不是则遍历2到num-1,把num的所有质数个数找出来,比如20可以分成2个2和一个5;选2有3种情况,选一个2\两个2或者不选,5也可以分为0或者1,组合出来的结果就是(2+1)*(1+1)=6。此题也是如此,找到一个数的所有质数个数,把每个质数个数+1全部乘起来就是ans。

    第三部,遍历a到b,找出div返回值最大的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.io.*;
public class Main{
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    static boolean[] isPrime;
    static int a,b;
    public static void main(String[] args) throws IOException {
        String[] temp=bf.readLine().split(" ");
        int a=Integer.parseInt(temp[0]);
        int b=Integer.parseInt(temp[1]);
        //欧拉筛
        isPrime=new boolean[b+1];
        isPrime[0]=isPrime[1]=true;
        for(int i=2;i*i<=b;i++) {
            if(!isPrime[i]) {
                for(int j=2*i;j<=b;j+=i) {
                    isPrime[j]=true;
                }
            }
        }
        long max=0;
        for(int i=a;i<=b;i++){
           max=Math.max(max,div(i));
        }
        pw.print(max);
        pw.flush();
    }
    public static long div(int num) {
        long ans=1;
        int[] arr=new int[num];
        //判段是否为质数
        if(!isPrime[num]) {
            return 2;
        }else {
        //存储当前变量,避免被下面运算修改
            int temp=num;
            //循环2至num-1,如果为质数就arr[i]++
            for(int i=2;i<num;i++) {
                if(!isPrime[i]) {
                    while(temp%i==0) {
                        temp/=i;
                        arr[i]++;
                    }
                }
            }
            //组合
            for(int i=1;i<num;i++) {
                if(arr[i]!=0) {
                    ans*=(arr[i]+1);
                }
            }
        }
        return ans;
    }
}

第三种方法:

这个其实是很容易的方法,但也是过这题的方法。

有点像欧拉筛,也是一个很好的方法,遍历1到b,把它的倍数存到相应的数组中去,这样就可以得到每个数的约数了。循环a-b,获得最大数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.*;
public class Main{
    static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    public static void main(String[] args) throws IOException {
    //读取
        String[] temp=bf.readLine().split(" ");
        int a=Integer.parseInt(temp[0]);
        int b=Integer.parseInt(temp[1]);
        int[] arr=new int[b+1];
        //遍历1到b,把他的倍数++
        for(int i=1;i<=b;i++) {
            for(int j=i;j<=b;j+=i) {
                arr[j]++;
            }
        }
        int max=0;
        for(int i=a;i<=b;i++) {
            max=Math.max(arr[i],max);
        }
        pw.print(max);
        pw.flush();
    }
}


点赞(0)
 

9.9 分

2 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论