[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解题思路和方法简直一毛一样...
同样我们引入这个公式:
对任一整数a>1,有a=p1a1p2a2…pnan,其中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 }