[HNOI2001]求正整数

题目描述

对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m。

例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6;而且是最小的有4个因子的整数。

输入输出格式

输入格式:

n(1≤n≤50000)

输出格式:

m

输入输出样例

输入样例#1:
INT.IN                 
4
输出样例#1:
INT.OUT
6
题解:

这道题和[HAOI 2007]反素数ant解题思路和方法简直一毛一样...

同样我们引入这个公式:

对任一整数a1,有a=p1a1p2a2pnan,其中p1<p2<<pn均为素数,而a1,a2…,an是正整数。

a的正约数个数为:(1+a1)(1+a2)(1+an)

同理,我们也是求有n个因数的最小整数。

我们最坏的情况所有质数只取1个,由于15<log250000<16

由于数字过大,这里用指数形式保存,用于比较大小

同时注意每层循环枚举取质数的个数时候,因为不合法的情况很多,可以只枚举√n次,然后用枚举的值算出对应的另外一个值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int len,p[21],prime[21],n,ans[21];
 8 double lg[21],maxx=2e9;
 9 void print(int x)
10 {int i,j,k;
11     long long s[100001],Mod=1e4;
12     memset(s,0,sizeof(s));
13     s[1]=1;len=1;
14      for (i=1;i<=x;i++)
15      {
16         for (j=1;j<=ans[i];j++)
17         {
18           for (k=1;k<=len;k++)
19            {
20              s[k]=s[k]*prime[i];
21            }
22            for (k=1;k<=len;k++)
23            s[k+1]+=s[k]/Mod,s[k]%=Mod;
24            while (s[len+1]) len++;
25         }
26      }
27       for (i=len;i>=1;i--)
28       if (i!=len)
29       printf("%04d",s[i]);
30       else printf("%d",s[i]);
31 }
32 void dfs(double s,int x,int k)
33 {int i;
34     if (s>=maxx) return;
35     if (k==1)
36     {
37         maxx=s;
38         memcpy(ans,p,sizeof(ans));
39         return;
40     }
41     if (x>16) return;
42     //cout<<p[x-1]<<endl;
43     for (i=0;(i+1)*(i+1)<=k;i++)
44     if (k%(i+1)==0)
45     {
46      if (i!=0)
47      {
48       p[x]=i;
49       dfs(s+i*lg[x],x+1,k/(i+1));
50       p[x]=0;
51      }
52      if ((i+1)*(i+1)!=k)
53      {
54         p[x]=k/(i+1)-1;
55         dfs(s+p[x]*lg[x],x+1,i+1);
56         p[x]=0;
57      }
58     }
59 }
60 int main()
61 {int i;
62     cin>>n;
63      prime[1]=2;prime[2]=3;prime[3]=5;prime[4]=7;prime[5]=11;
64      prime[6]=13;prime[7]=17;prime[8]=19;prime[9]=23;
65      prime[10]=29;prime[11]=31;prime[12]=37;prime[13]=41;
66      prime[14]=43;prime[15]=47;prime[16]=53;
67      for (i=1;i<=16;i++)
68      lg[i]=(double)log(prime[i]);
69     dfs(0,1,n);  
70     //for (i=1;i<=16;i++)
71     //cout<<ans[i]<<endl;
72     print(17);
73 }

 

posted @ 2017-08-22 22:07  Z-Y-Y-S  阅读(713)  评论(0编辑  收藏  举报