题目链接https://vjudge.net/problem/UVA-294
题目大意,求一个区间内哪个数的约数最多,输出该数和其约数的数目
例如 3-10 6的约数最多有4个(1 2 3 6)
求取约数个数公式
m=(p1)^(x1)*(p2)^(x2)*(p3)^(x3)*……
其中p1,p2,p3...是质数(素数),x1,x2,x3...是它们的指数
则m的约数的个数是(x1+1)*(x2+1)*(x3+1)*……
例如24=(2^3) * (3^1)
所以其约数的个数为(3+1)*(1+1)=8个
例如10=2^1*5^1 约数个数=(1+1)*(1+1)=4 ,1 2 5 10
代码:先打一个素数表,遍历
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int T,a,b,k;
static final int max=(int) 1e6;//这里直到1e6,因为题干中1e9开根号为1e5,1e6完全可以包括1e9的约数,因为1不是素数不会到1e9,例如判断素数的条件是2-根号n,可能说的不太明白但就像15的约数不会超过根号15,最大是5;
static boolean vis[]=new boolean[ max];
static int prime[]=new int[max];
public static void prime() {//欧拉素数筛,把1e6之中的素数保存到数组中
Arrays.fill(vis,true);
vis[0]=vis[1]=false;
k=0;
for(int i=2;i<max;i++){
if(vis[i]==true)
prime[k++]=i;
for(int j=0;j<k&&i*prime[j]<max;j++){
vis[i*prime[j]]=false;
if(i%prime[j]==0){
break;
}
}
}
}
static void divisor(int a,int b){//判断约数数目max
int max=0, maxi=0;
for(int i=a;i<=b;i++){//遍历a-b
int sum=1;
for(int j=0;j<k;j++){遍历素数数组,套约数公式
int t=i;
int sum2=1;
if(prime[j]>t) break;//如果素数超过本身了,也就没有向下计算的必要了
while(t%prime[j]==0){//如果整除,计算t%prime[j]^r,r的大小
sum2++;//公式ri++;
t=t/prime[j];
}
sum*=sum2;
}
if(sum>max){//判断max
max=sum;
maxi=i;
}
}
System.out.println("Between "+a+" and "+b+", "
+maxi+" has a maximum of "+max+" divisors.");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
prime();
T=sc.nextInt();
while(T>0){
a=sc.nextInt();
b=sc.nextInt();
divisor(a,b);
T--;
}
}
}