Let P1, P2, … ,PN, … be a sequence of prime numbers. Super-prime number is such a prime number that its current number in prime numbers sequence is a prime number too. For example, 3 is a super-prime number, but 7 is not. Index of super-prime for number is 0 iff it is impossible to present it as a sum of few (maybe one) super-prime numbers, and if such presentation exists, index is equal to minimal number of items in such presentation. Your task is to find index of super-prime for given numbers and find optimal presentation as a sum of super-primes.
Input
There is a positive integer number in input. Number is not more than 10000.
Output
Write index I for given number as the first number in line. Write I super-primes numbers that are items in optimal presentation for given number. Write these I numbers in order of non-increasing.
Sample Input
6
Sample Output
2 3 3
超级质数:一个质数在质数序列里的下标也是质数,那么这个数称为超级质数。
给定一个数n,问你这个数是不是若干个超级质数的和。
如果是,输出最小能由多少个超级质数构成,并输出这些超级质数(这些超级质数可以重复)
如果不是,输出0。
我们可以先预处理出来所有的超级质数,然后再跑一遍完全背包,并记录一下路径,就可以了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int inf = 1e8;
const int maxn = 10010;
int p[maxn],f[maxn];
int cnt = 0;
void init()
{
LL i,j;
f[1] = 1;
for(i=2;i<maxn;i++)
{
if(f[i])
continue;
p[++cnt] = i;
for(j=i*i;j<maxn;j+=i)
{
f[j] = 1;
}
}
int tcnt = 0;
for(i=1;i<=cnt;i++)
{
if(f[i] == 0)
p[++tcnt] = p[i];
}
cnt = tcnt;
}
int dp[maxn],pre[maxn];
void print(int x)
{
if(x == 0)
{
return;
}
printf("%d",x-pre[x]);
if(pre[x] == 0)
printf("\n");
else
printf(" ");
print(pre[x]);
}
int main(void)
{
init();
int n,i,j;
while(scanf("%d",&n)==1)
{
for(i=1;i<=n;i++)
dp[i] = inf;
memset(pre,0,sizeof(pre));
dp[0] = 0;
for(i=1;i<=cnt;i++)
{
for(j=p[i];j<=n;j++)
{
if(dp[j] > dp[j-p[i]] + 1)
{
dp[j] = dp[j-p[i]] + 1;
pre[j] = j - p[i];
}
}
}
if(dp[n] == inf)
{
printf("0\n");
continue;
}
printf("%d\n",dp[n]);
print(n);
}
return 0;
}