ural 1748
题目:http://acm.timus.ru/problem.aspx?space=1&num=1748
题意:定义:一个数的的因子个数称为该数的复杂度,给出一个n,求从 1 ~ n 范围内复杂度最大的数,如果有多个相等,输出最小的,并输出因子个数
其实就是求反素数的(关于反素数:http://www.cnblogs.com/fxh19911107/archive/2012/07/28/2613150.html),先用求反素数的模板求出在n 范围内复杂度最大的数,然后再把 这个数分解成 素数 乘积的形式,求出因子数
View Code
1 typedef long long ll; 2 const int prime[20]= {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67}; 3 ll maxsum,bestnum,n; 4 ll dnum; 5 void getantiprime(ll num,ll k,ll sum,int limit) 6 { 7 int i; 8 ll temp; 9 if(sum > maxsum) 10 { 11 maxsum = sum; 12 bestnum = num; 13 } 14 if(sum == maxsum && bestnum > num) 15 bestnum = num; 16 if(k > 15) 17 return ; 18 temp = num; 19 for(i = 1; i <= limit; i++) 20 { 21 if(n / temp < prime[k]) break; // 注意这里,因为以前写那个模板时 是用 temp * prime[k] < n 来作为判断条件的,结果就在 10 ^ 8溢出了, 22 temp = temp * prime[k]; 23 if(temp <= n) getantiprime(temp,k + 1,sum * (i + 1),i); 24 } 25 } 26 void cal(ll tt) // 求最大复杂度数的因子个数,其实不用这样求也可以,因为在求反素数时,maxsum记录的就是该数的因子个数,直接用的以前写的,所以就贴过来了 27 { 28 int i; 29 for(i = 1; i < 16; i++) 30 { 31 if(tt % prime[i] == 0) 32 { 33 ll sum = 0; 34 while(tt % prime[i] == 0) 35 { 36 sum ++; 37 tt /= prime[i]; 38 } 39 dnum *= (sum + 1); 40 } 41 } 42 } 43 int main() 44 { 45 int t; 46 //freopen("data.txt","r",stdin); 47 scanf("%d",&t); 48 while(t--) 49 { 50 maxsum = -1; 51 scanf("%lld",&n); 52 getantiprime(1,1,1,50); 53 dnum = 1; 54 ll tbest = bestnum; 55 cal(tbest); 56 printf("%lld %lld\n",bestnum, dnum); 57 } 58 return 0; 59 }