AcWing 1296. 聪明的燕姿
聪明的燕姿
思路:
1.假设这个时候有一个约数和S满足, 就已经接近1e9的量级了,大概满足条件的不会超过9或者10个质数,可见符合条件的项不会很多那么这个时候我们就可以用dfs进行搜索。
2.考虑dfs遍历顺序:第一层遍历质数P,第二层遍历指数C,如果当前的和s取模为0则进去下一层循环
3.题目的s为2e9范围内的质数有 ,有六七千万的质数,需要考虑如何剪枝:特殊情况如果 则直接输出即可导致会出现两种情况:
1.
2.
可以看出
所以dfs枚举的即为的范围内
4.dfs过程中由于我们枚举的质数是单调递增的,所以除后当前的s - 1必须大于上一层质数
样例输入:
42
样例输出:
3
20 26 41
代码:
//import
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long LL;
const int N = 1e5;
int n;
int primes[N], cnt;
bool st[N];
int ans[N], len;
//筛质数
void init()
{
for(int i = 2; i <= N; i ++ )
{
if(!st[i]) primes[cnt ++] = i;
for(int j = 0; primes[j] <= N / i; j ++ )
{
st[i * primes[j]] = true;
if(i % primes[j] == 0) break;
}
}
}
//判断是否是质数
bool is_prime(int x)
{
if (x < N) return !st[x];
for (int i = 0; primes[i] <= x / primes[i]; i ++ )
if (x % primes[i] == 0)
return false;
return true;
}
void dfs(int s, int idx, int pro)
{
if(s == 1)
{
ans[len ++] = pro;
return;
}
//对s - 1进行特判 并且当前的s - 1 大于上一层的质数
if(s - 1 > (idx < 0 ? 1 : primes[idx]) && is_prime(s - 1))
ans[len ++] = pro * (s - 1);
for(int i = idx + 1; primes[i] <= s / primes[i]; i ++ )
{
int p = primes[i];
for(int j = 1 + p, t = p; j <= s; t *= p, j += t) // tip
if(s % j == 0)
dfs(s / j, i, pro * t);
}
}
int main()
{
init();
while (cin >> n)
{
len = 0;
dfs(n, -1, 1);
cout << len << endl;
if (len)
{
sort(ans, ans + len);
for (int i = 0; i < len; i ++ ) cout << ans[i] << ' ';
cout << endl;
}
}
return 0;
}