题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84562#problem/C
题意:
输入正整数n,把整数1,2,3,。。。,n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好输出一次。n<=16。
注意:它是环,最后一个数加上1也要为素数。
案例:
input
6
8
output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
思路分析:需要找到所有可行解,则可用DFS,回溯法,但要注意,是找到所有可行解,所以在返回是要清除标志。
源代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int n,a,c[20],idx[20],i,j,t,m=0; 6 void dfs(int h) 7 { 8 if(h==n) //递归边界 9 { 10 t=0; 11 for(j=2;j<(c[h-1]+1);j++) 12 if((c[h-1]+1)%j==0) 13 t++; 14 if(t==0) 15 { 16 cout<<c[0]; 17 for(i=1;i<n;i++) 18 cout<<" "<<c[i]; 19 cout<<endl;return;} 20 } 21 for(int i=1;i<=n;i++) //这里的i必须为局部变量 22 { 23 t=0; 24 if(h==0&&i!=1)continue; 25 a=c[h-1]+i; 26 for(j=2;j<a;j++) //判断是否为素数 27 if(a%j==0) 28 t++; 29 if(t==0&&idx[i]!=1) 30 { 31 idx[i]=1; 32 c[h]=i; //设置使用标志 33 dfs(h+1); 34 idx[i]=0; //清除标志 35 } 36 } 37 } 38 int main() 39 { 40 while(scanf("%d",&n)!=EOF) 41 { 42 if(m)cout<<endl; 43 m++; 44 printf("Case %d: ",m); 45 memset(idx,0,sizeof(idx)); 46 dfs(0); 47 } 48 return 0; 49 }