本题要找的是n到m的所有整数中,因数最多那个数,并输出其有几个因数。
这里我们要知道的是,每个正整数(1除外)都可以被分解为素数之积。 这其实在做素数的筛法中就可以发现,每个数都会被这个数之前的素数的积筛出来,那也就说明正整数由素数本身,(一个或多个)素数的积,和1组成。
这又叫唯一因式分解。
下附一张分解式的图,来源百度文库共享文档。
那么对于本题,我们要做的就是枚举(√ ̄100000000)以内的素数,确保组成范围数字的素数能全部枚举到。 然后暴力对n到m间的数字求因数找最大值。因数个数= (每个素数因子个数+1)的积。
代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include <algorithm>
using namespace std;
const long N = 40000;
long prime[N] = {0},num_prime = 0;
int isNotPrime[N] = {1, 1};
int main(){
int T,n,m;
//素数筛
for(long i = 2 ; i < N ; i ++){
if(! isNotPrime[i])
prime[num_prime ++]=i;
for(long j = 0 ; j < num_prime && i * prime[j] < N ; j ++){
isNotPrime[i * prime[j]] = 1;
if( !(i % prime[j] ) )
break;
}
}
//
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
int Max=0,site=1;
for(int i=n;i<=m;i++){
int temp=i,ans=1;
for(int j=0;j<num_prime;j++){
int CiFang=1;
while(!(temp%prime[j])){
temp/=prime[j];
CiFang++;
}
//printf("i=%d temp=%d prime=%d cifang=%d\n",i,temp,prime[j],CiFang);
ans*=CiFang;
if(temp==1)
break;
}
if(ans>Max){
Max=ans;
site=i;
}
//printf("Max=%d\n",Max);
}
printf("Between %d and %d, %d has a maximum of %d divisors.\n",n,m,site,Max);
}
return 0;
}