炫酷数字(C)
题目描述
小希希望你构造一个最小的正整数,使得其有n个因子。
输入描述:
第一行一个整数T表示数据组数
每组数据第一行输入一个正整数n,表示其因子数。
n≤1,000,000
T≤1,000,000
输出描述:
输出一行一个整数,表示你构造出的这个数。注意:你需要保证你构造的数≤1,000,000,如果在这个范围里面无法构造出一个正整数满足条件,请输出-1。
示例1
输入
2
4
5
输出
6
16
题目思路:
该题目可以直接打表,甚至可以OEIS。
根据唯一分解定理,如果一个数n可以表示成
n
=
Π
i
=
1
k
p
i
a
i
=
p
1
a
1
p
2
a
2
.
.
.
∗
p
k
a
k
n=Π_{i=1}^kp_i^{a_i}=p_1^{a_1}p_2^{a_2}...∗p_k^{a_k}
n=Πi=1kpiai=p1a1p2a2...∗pkak
那么n的因数的个数为
Π
i
=
1
k
(
a
i
+
1
)
=
(
a
1
+
1
)
(
a
2
+
1
)
.
.
.
∗
(
a
k
+
1
)
Π_{i=1}^k(a_i+1)=(a_1+1)(a_2+1)...∗(a_k+1)
Πi=1k(ai+1)=(a1+1)(a2+1)...∗(ak+1)
所以可以通过类似调和级数的方法O(nlogn)求解。
或者扩展埃式筛法之类也可。
即代码就在实现算法的过程。
解题代码:
#include <algorithm>
#include <cstring>
using namespace std;
const int inf = 0x3f3f3f;//巧妙设计无穷大,使得可以使用memset(a,inf,sizeof(a))使每个字节都是无穷大
const int N = 1e6+5;
int a[N],f[N];
int main()
{
int T,n;
memset(a,inf,sizeof(a));
for(int i=1;i<=1000000;++i)
{
for(int j=i;j<=1000000;j+=i) f[j]++;
a[f[i]] = min( a[f[i]], i );
}
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(a[n]>1000000) printf("-1\n");
else printf("%d\n",a[n]);
}
}
笔记:
关于const int inf = 0x3f3f3f;的一些常识可以参考博客https://blog.csdn.net/jiange_zh/article/details/50198097