Description
对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m。例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6;而且是最小的有4个因子的整数。
Input
n(1≤n≤50000)
Output
m
Sample Input
4
Sample Output
6
题解
这道题和[HAOI 2007]反素数ant解题思路和方法简直一毛一样...
同样我们引入这个公式:
对任一整数$a>1$,有$a={p_1}^{a_1}{p_2}^{a_2}…{p_n}^{a_n}$,其中$p_1<p_2<…<p_n$均为素数,而$a_1$,$a_2$…,$a_n$是正整数。
$a$的正约数个数为:$(1+a_1)(1+a_2)…(1+a_n)$
同理,我们也是求有$n$个因数的最小整数。
我们最坏的情况所有质数只取$1$个,由于$15<log_{2}50000<16$
所以只要取前$16$个质数即可,
其余都和之前那题一样...
搜的时候为了保存最优值,因为数据大会爆$long$ $long$我们考虑用指数幂的形式保存,带一个数组保存取质数的个数。
同时注意每层循环枚举取质数的个数时候,因为不合法的情况很多,可以只枚举$sqrt n$次,然后用枚举的值算出对应的另外一个值。
1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<ctime> 5 #include<queue> 6 #include<stack> 7 #include<cstdio> 8 #include<string> 9 #include<vector> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 using namespace std; 15 const double INF=1e100; 16 const int pri[18]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; 17 18 int n; 19 double lg[18],mm=INF; 20 int ans[18],tmp[18]; 21 22 void Dfs(double e,int y,int cen) 23 { 24 if (e>=mm) return; 25 if (y==1) 26 { 27 mm=e; 28 memcpy(ans,tmp,sizeof(ans)); 29 return; 30 } 31 if (cen>16) return; 32 for (int i=0;(i+1)*(i+1)<=y;i++) if (!(y%(i+1))) 33 { 34 if (i!=0) 35 { 36 tmp[cen]=i; 37 Dfs(e+lg[cen]*i,y/(i+1),cen+1); 38 tmp[cen]=0; 39 } 40 if ((i+1)*(i+1)!=y) 41 { 42 tmp[cen]=y/(i+1)-1; 43 Dfs(e+lg[cen]*(y/(i+1)-1),i+1,cen+1); 44 tmp[cen]=0; 45 } 46 } 47 } 48 void print() 49 { 50 const int MOD=1e4; 51 int a[100000],maxn=1; 52 a[1]=1; 53 for (int i=1;i<=16;i++) 54 { 55 for (int j=1;j<=ans[i];j++) 56 { 57 for (int k=1;k<=maxn;k++) a[k]*=pri[i]; 58 for (int k=1;k<=maxn;k++) a[k+1]+=a[k]/MOD,a[k]%=MOD; 59 if (a[maxn+1]) maxn++; 60 } 61 } 62 printf("%d",a[maxn]); 63 for (int i=maxn-1;i>=1;i--) printf("%04d",a[i]); 64 printf(" "); 65 } 66 67 int main() 68 { 69 scanf("%d",&n); 70 for (int i=1;i<=16;i++) lg[i]=log(pri[i]); 71 Dfs(0,n,1); 72 print(); 73 return 0; 74 }