首页 > 技术文章 > 5G.炫酷数字(C)

yuzilan 2019-02-15 16:44 原文

炫酷数字(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=1kpiai=p1a1p2a2...pkakn=Π_{i=1}^kp_i^{a_i}=p_1^{a_1}p_2^{a_2}...∗p_k^{a_k}
那么n的因数的个数为Πi=1k(ai+1)=(a1+1)(a2+1)...(ak+1)Π_{i=1}^k(a_i+1)=(a_1+1)(a_2+1)...∗(a_k+1)
所以可以通过类似调和级数的方法O(nlog⁡n)求解。
或者扩展埃式筛法之类也可。
即代码就在实现算法的过程。

解题代码:

#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

推荐阅读