题意:给 3 个整数 n, m ,d,求一个最小字母序的序列,包含 n 到 m 之间的所有数字,并且任意连续 2 个数、3个数... 到d 个数的和都不是素数。
解法:先把素数筛出来,然后暴力 dfs.
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int num[1001],d,n,m;
bool ever[1001],isprime[10010],flag;
//检查加入 x 后是否还符合条件
bool check(int len, int x)
{
int sum = x;
for(int i = len - 1;i >= 0 && i > len - d ;--i)
{
sum += num[i];
if(isprime[sum]) return false;
}
return true;
}
//len 代表已选中的数的个数
void dfs(int len)
{
if(len == m - n + 1 || flag )
{
flag = true;
return ;
}
for(int i = n;i <= m;++i)
{
if(!ever[i] && check(len, i) && !flag)
{
num[len] = i;
ever[i] = 1;
dfs(len + 1);
ever[i] = 0;
}
}
}
int main()
{
memset(isprime,1,sizeof(isprime));
for(int i = 2;i < 101;++i)
{
if(isprime[i])
{
for(int j = i*i;j < 10001;j += i)
isprime[j] = false;
}
}
isprime[1] = 0;
while(scanf("%d%d%d",&n,&m,&d),n + m)
{
memset(ever,0,sizeof(ever));
flag = false;
dfs(0);
if(flag)
{
printf("%d",num[0]);
for(int i = 1;i <= m - n;++i)
printf(",%d",num[i]);
printf("\n");
}
else
printf("No anti-prime sequence exists.\n");
}
return 0;
}