一道不错的搜索入门题.
题目大意:
http://poj.org/problem?id=2034
给你三个数,n,m,d 要求从n到m之间的n-m+1个数组成一个序列,有如下特点:
1.连续2-d个数的合不能为素数
2.若没有这样的序列,输出
No anti-prime sequence exists.如样例2:
1,3,5,4,6,2,10,8,7,9其中: 3,5,4 5,4,6 6,2,10 等等均不为素数,10,8 8,7 等也不为素数
解题思路:
因为d只有10,暴力DFS搜索,最坏为1000*10*10.先打10000的素数表.
搜索方式,对每一位枚举,同时由rec函数判定,这个数与其连续后d个数的合是否素数.剪枝方面没什么好的方法~
源代码:
#include <myhead>
const int M=10011;
const int N=1001;
int n,m,d,num;
bool _hash[N],prim_hash[M];
int result[N];
void prim()
{
memset(prim_hash,0,sizeof(prim_hash));
prim_hash[0]=prim_hash[1]=true;
for(int i=2;i<=100;++i) {
if(!prim_hash[i]) {
for(int j=i+i;j<M;j+=i)
prim_hash[j]=true;
}
}
}
inline bool rec(int index,int value)
{
if(index==0)
return true;
int left=index-d+1;
left=max(left,0);
for(int i=index-1;i>=left;--i) {
value+=result[i];
if(!prim_hash[value])
return false;
}
return true;
}
bool dfs(int index)
{
if(index==num)
return true;
for(int i=n;i<=m;++i) {
if(!_hash[i]&&rec(index,i)) {
_hash[i]=true;
result[index]=i;
if(dfs(index+1))
return true;
_hash[i]=false;
}
}
return false;
}
int main()
{
prim();
while(~scanf("%d%d%d",&n,&m,&d),n) {
num=m-n+1;
memset(result,0,sizeof(result));
memset(_hash,0,sizeof(_hash));
if(dfs(0)) {
printf("%d",result[0]);
for(int i=1;i<num;++i)
printf(",%d",result[i]);
puts("");
}else
puts("No anti-prime sequence exists.");
}
return 0;
}