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  }
原文地址:https://www.cnblogs.com/fxh19911107/p/2686987.html