题目描述
把一个自然数N的正因子个数记为F(N),例如18的所有正因子为1,2,3,6,9,1,8,所以F(18)=6。现在给出K,请你求出所有满足F(N)=K的N中最小的数。
输入格式
第1行为K,其中0<K<=80。
输出格式
如果存在不大于20000的解,则输出这个N,并输出相应的K个因子,否则输出“NO SOLUTION”。
样例数据
input
9
output
36
1 2 3 4 6 9 12 18 36
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 20010;
int prime[N], cnt;
int factors_cnt[N];
vector<int> factors[N];
void get_factors() //预处理1~N中每个数的因数
{
for(int i=1; i<=N; i++)
for(int j=i; j<=N; j+=i)
factors_cnt[j] ++, factors[j].push_back(i);
}
void get_primes() // 预处理质数
{
bool st[N] = {false};
for (int i = 2; i <= N; i ++ )
{
if (!st[i]) prime[cnt ++ ] = i;
for (int j = 0; prime[j] <= N / i; j ++ )
{
st[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
}
int main()
{
get_factors();
get_primes();
int k;
cin >> k;
for(int i=1; i<=N; i++)
{
if(factors_cnt[i] == k) // 只检查正整数
{
bool is_prime = true; // 是否为质数
for(int j=0; j<factors[i].size(); j++)
{
int x = factors[i][j];
if(x != 1 && x != i && factors_cnt[x] == 1) // 如果有两个以上的约数,它就不是质数
{
is_prime = false;
break;
}
}
if(is_prime)
{
printf("%d\n", i);
for(int j=0; j<factors[i].size(); j++)
printf("%d ", factors[i][j]);
return 0;
}
}
}
puts("NO SOLUTION");
return 0;
}