UVA 294 Divisors
题意是求l到u之间因子总数最多的数。
原理还是唯一分解定理。
简单分析可知,将6质因数分解,6=2*3,所以说6的因子可以是2^0*3^0, 2^1*3^0, 2^0*3^1, 2^1*3^1, 即1,2,3,6,个数相当于(C1 2)*(C 1 2)每个因子可以选择1个或0个2或3相乘,选择0个等于1,a^0=1(a>0)。
同理,将1000质因数分解,1000=2^3*5^3,所以说1000的因子是16个,个数相当(C 1 4)*C(1 4),每个因子可以选择0/1/2/3个2相乘。
所以解决的思路是,预处理数组存(C 1 n),再对每个数进行质因数分解,然后将所有质因子的(C 1 n)相乘,其中n表示该质因子次方数+1.
看到别人的代码没有预存(C 1 n),由于(C 1 n)=n+1,每次直接计算就好。
注意,当l=u=1时,答案是1.
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 using namespace std; 5 6 int main(){ 7 8 int n,l,u,f,flag[100000],min,m,ans,maxans,maxansd; 9 int lg[30]; 10 for(int i=0;i<=30;i++) lg[i]=i+1; 11 scanf("%d",&n); 12 13 for(int i=0;i<n;i++){ 14 maxans=1;maxansd=1; 15 scanf("%d%d",&l,&u); 16 for (int a=l;a<=u;a++){ 17 memset(flag,0,sizeof(flag)); 18 f=0; 19 ans=1; 20 m=a; 21 min=(int)sqrt(m+1); 22 for (int b=2;b<=min;b++){ 23 if (m%b==0) { 24 f++; 25 while(m%b==0) { 26 m =m/b; 27 flag[f]++; 28 } 29 } 30 } 31 if (m!=1) ans=2; 32 for (int c=1;flag[c]>0;c++ ) 33 ans*=lg[flag[c]]; 34 if (ans>maxans) { 35 maxans=ans; 36 maxansd=a; 37 } 38 } 39 printf("Between %d and %d, %d has a maximum of %d divisors.\n",l,u,maxansd,maxans); 40 41 } 42 }