深搜 soj 1002. Anti-prime Sequences
问题描述 翻译
给定一个连续整数序列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"; } }