题意:给定区间[n,m]和d求一个排列使得连续的小于等于d且大于1长度的序列之和为合数。
题解:dfs+剪枝即可
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int mr=10050; 6 bool notp[mr]; 7 int pr[mr]; 8 int pn; 9 void getpri()//筛素数 10 { 11 memset(notp,0,sizeof(notp)); 12 pn=0; 13 for(int i=2; i<mr; i++) 14 { 15 if(!notp[i]) 16 { 17 pr[pn++]=i; 18 } 19 for(int j=0; j<pn && i*pr[j]<mr; j++) 20 { 21 int k=i*pr[j]; 22 notp[k]=1; 23 if(i%pr[j]==0) 24 { 25 break; 26 } 27 } 28 } 29 } 30 int n,m,d; 31 int ans[1005],temp[1005]; 32 bool vis[1005]; 33 bool dfs(int k,int sum[]) 34 { 35 if(k==m-n+1) 36 { 37 memcpy(ans,temp,sizeof(temp)); 38 return true; 39 } 40 for(int i=n,j;i<=m;i++) 41 { 42 if(!vis[i]) 43 { 44 int s[15]; 45 s[1]=i; 46 for(j=2;j<=d;j++) 47 { 48 if(sum[j-1]==0) 49 { 50 s[j]=0; 51 continue; 52 } 53 s[j]=sum[j-1]+i; 54 if(!notp[s[j]]) 55 break; 56 } 57 if(j<=d) 58 continue; 59 vis[i]=true; 60 temp[k]=i; 61 if(dfs(k+1,s)) 62 return true; 63 vis[i]=false; 64 } 65 } 66 return false; 67 } 68 int main() 69 { 70 getpri(); 71 notp[0]=true; 72 while(scanf("%d%d%d",&n,&m,&d),(n||m||d)) 73 { 74 int sum[15]; 75 memset(sum,0,sizeof(sum)); 76 memset(vis,false,sizeof(vis)); 77 if(dfs(0,sum)) 78 { 79 int i,len=m-n; 80 for(i=0;i<len;i++) 81 printf("%d,",ans[i]); 82 printf("%d\n",ans[len]); 83 } 84 else 85 { 86 printf("No anti-prime sequence exists.\n"); 87 } 88 } 89 return 0; 90 }