首先了解一点,求解一个数的因子个数。
假设p[]数组里全部是素数,那么任何一个整数,可以唯一的表示成n=p1^x1*p2^x2*p3^x3.......*pm^xm,那么因子个数便为:(x1+1)*(x2+1)*.....*(xm+1)。
给定一个整数n,求解1~~n范围内,因子个数最多的那个数,如果相同的话,取较小的。
这里要认识到一点,因子数最多的那个数,根据我们上面说的,可以由素数的乘积组成。那么我们枚举素数的幂,也就是上面式子上的x1,x2,x3...xm。就可以遍历到1~~n范围内的所有可能解。假设n的取值范围是10^18次方,看起来很大是吧,对于素数2来说,2^60次方就大于10^18次方了,而且我们可以发现,上面的式子中x1>=x2>=x3>=....xm。而最大的那个也最多只有60次枚举,所以说,枚举起来速度是很快的。
View Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 int prim[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; 7 __int64 n; 8 __int64 ans; //答案 9 int complexity; //因子个数 10 11 void dfs(int k,int limited,__int64 now,int com) //目前在第k个素数,最多搜索limited次,now是目前的数,com是目前的因子数 12 { 13 if(now>n) 14 return; 15 if(com>complexity) 16 { 17 complexity=com; 18 ans=now; 19 } 20 if(com==complexity && now <ans) 21 ans=now; 22 if(k>15) 23 return; 24 int i; 25 __int64 m=now; 26 for(i=1;i<=limited;i++) 27 { 28 if(m*prim[k]>n) 29 break; 30 m=m*prim[k]; 31 dfs(k+1,i,m,com*(i+1)); 32 } 33 } 34 35 int main() 36 { 37 while(scanf("%I64d",&n)==1) 38 { 39 complexity=0; 40 ans=0; 41 dfs(0,60,1,1); 42 printf("%I64d %d\n",ans,complexity); 43 } 44 return 0; 45 }