问题描述 翻译
给定一个连续整数序列n, n+1, n+2, … , m,一个反素数序列是这些整数的一个重排,使得每对相邻的整数和为合数。例如,若n = 1且m = 10,那么1, 3, 5, 4, 2, 6, 9, 7, 8, 10就是一个反素数序列。它也是按字典顺序的第一个这样的序列。
我们可以扩展此定义,度d反素数序列是相邻d个整数之和为合数的这种序列。所以,之前的序列是一个度2反素数序列,但是不是度3的,因为子列5, 4, 2和为11。这些数按字典顺序的第一个度3反素数序列为1, 3, 5, 4, 6, 2, 10, 8, 7, 9。
问题解释
这里要求你找的不仅仅是所有的含d个元素的子序列之和都为合数,而是使得最后的序列要满足d=2,3,4,5,6.....n 各种情况下连续子序列之和都为合数,这个时候可以采用深搜的方法,先产生一个长度为1的序列,判断加入序列的元素能否满足题目所给的条件,即新序列的度能否达到d,若所有元素都被添加到序列中,则产生了一个度为n的反素数序列。
#include <iostream>
#include <memory.h>
using namespace std;
const int Size = 1001;
int sequence[Size];
int prime_suquence[10001]={0};
int sub_len, bot,top;
bool visited[Size];
bool flag;
void produce_prime(){
memset(prime_suquence,1,sizeof(prime_suquence));
for( int i=2; i<100; ++i ){
if( prime_suquence[i] ){
for( int j=2; j*i < 10001; ++j)
prime_suquence[i*j] = 0;
}
}
}
//小规模素数筛选法
bool is_prime(int depth,int pos){
int sum = pos;
for( int i=2; i<=sub_len && depth - i >= 0; ++i )
{
sum += sequence[ depth - i ];
if( prime_suquence[sum] )
return false;
}
return true;
}
void produe_sequence(int depth){
if( depth == top - bot + 2 ){
flag = 0;
cout << sequence[0];
for( int i=1; i<top-bot+1; ++i) cout << ','<< sequence[i];
cout << endl;
return;
}
for( int i=bot; i<=top&&flag; ++i ){
if( visited[i] == 0 ){
if( is_prime(depth,i) ){
visited[i] = 1;
sequence[depth-1] = i;
produe_sequence(depth+1);
visited[i] = 0;
}
}
}
}
int main(){
produce_prime();
while( cin >> bot >> top >> sub_len , bot != 0 || top != 0 || sub_len != 0 ){
int start = bot;
flag = 1;
for( int i=bot; i<=top&&flag; ++i )
{
visited[i] = 1;
sequence[0] = i;
produe_sequence(2);
visited[i] = 0;
}
if( flag )
cout << "No anti-prime sequence exists.\n";
}
}