[HNOI 2001]求正整数

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("\n");
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 }

 

posted @ 2017-08-22 16:34  NaVi_Awson  阅读(358)  评论(0编辑  收藏  举报