Divisors UVA - 294 (区间内约数最多的数和它因子的个数)

Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an
interesting number, since it is the first odd number for which the sum of its divisors is larger than the
number itself.
To help them search for interesting numbers, you are to write a program that scans a range of
numbers and determines the number that has the largest number of divisors in the range. Unfortunately,
the size of the numbers, and the size of the range is such that a too simple-minded approach may take
too much time to run. So make sure that your algorithm is clever enough to cope with the largest
possible range in just a few seconds.
Input
The first line of input specifies the number N of ranges, and each of the N following lines contains a
range, consisting of a lower bound L and an upper bound U, where L and U are included in the range.
L and U are chosen such that 1 ≤ L ≤ U ≤ 1000000000 and 0 ≤ U − L ≤ 10000.
Output
For each range, find the number P which has the largest number of divisors (if several numbers tie for
first place, select the lowest), and the number of positive divisors D of P (where P is included as a
divisor). Print the text ‘Between L and H, P has a maximum of D divisors.’, where L, H, P,
and D are the numbers as defined above.
Sample Input
1 10
1000
1000000000
Sample Output
Between 1 and 10, 6 has a maximum of 4 divisors.
Between 1000 and 1000, 1000 has a maximum of 16 divisors.
Between 999999900 and 1000000000, 999999924 has a maximum of 192 divisors.

思路:先欧拉素数筛筛出素数,再根据约数分解定理求解:https://blog.csdn.net/daoshen1314/article/details/102684698

代码:
   

import java.util.Arrays;
import java.util.Scanner;

public class main2 {
	static final int max=(int)34000;
	static int prime[]=new int[max];
	static boolean[] vis=new boolean[max];
	static int k=0;
	public static void Prime(){
		Arrays.fill(vis, true);
		vis[0]=vis[1]=false;
		for(int i=2;i<max;i++){
			if(vis[i]) prime[k++]=i;
			for(int j=0;j<k&&(long)i*prime[j]<max;j++){
				vis[i*prime[j]]=false;
				if(i%prime[j]==0) break;
			}
		}
	}
	public static int count(int x){
		 int sum=1;
		 for(int i=0;i<k;i++){
			 int cnt=0;
			 while(x%prime[i]==0){
				 cnt++;
				 x/=prime[i];
			 }
			 sum*=(cnt+1);
			 if(x==1) break;
		 }
		 return sum;
	}
    public static void main(String[] args) {
    	 Prime();
		 Scanner scan=new Scanner(System.in);
		 int t=scan.nextInt();
		 while(t!=0){
		 int l=scan.nextInt();
		 int r=scan.nextInt();
		 int max=0,index=0;
		 for(int i=l;i<=r;i++){
			  int ans=count(i);
			  if(ans>max){
				  max=ans;
				  index=i;
			  }
		 }
		 System.out.println("Between "+l+" and "+r+", "+index+" has a maximum of "+max+" divisors.");
		 t--;
		 }
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ksuper&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值