意思是给你一个数n,要构成一个素数环,这个素数由1-n组成,它的特征是选中环上的任意一个数字i,i与它相连的两个数加起来都分别为素数,满足就输出。

这个题的做法和hdu1015做法差不多都是使用dfs 回溯。不同之处在于这个要全部搜索,而hdu1015只需要搜索第一组就可以。 其次在这个题目中使用素数打表的方式简化素数判定,在一定情况下也是对效率有所提高的。

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 34615 Accepted Submission(s): 15331

Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.

Note: the number of first circle should always be 1.

Input n (0 < n < 20).

Output The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.

You are to write a program that completes above process.

Print a blank line after each case.

Sample Input

6 8

Sample 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

#include <cstdio>
#include <cmath>
#include <cstring>
#define maxn 20
using namespace std;
bool dp[maxn][maxn];//记忆素数数组
int n;
bool isvisited[maxn+3];
int m[maxn+3];

void is_prime(){ for(int i=1;i<20;i++) for(int j=1;j<20;j++){ int test=i+j; int flag=0; for(int x=2;x*x<=test;x++){ if(test%x==0){ dp[i][j]=false; flag=1; break; } } if(!flag) dp[i][j]=true; } }

void pt(){ int first=0; for(int i=1;i<=n;i++){ if(first) printf(" "); else first=1; printf("%d",m[i]); } printf("\n"); }

void dfs(int k){ //选到最后一个了 //肯定不能忘了判定是否与第一个1加起来是素数 if(k==n&&dp[m[k]][1]){ //执行打印任务 pt(); return ; } for(int i=2;i<=n;i++) //判断这个数用过没有 if(isvisited[i]==false){ if(dp[i][m[k]]){//查表,判定加和是否为素数 isvisited[i]=true;//标记使用状态 m[k+1]=i;//当前值已经可取 dfs(k+1);//向下搜索 isvisited[i]=false;//回溯 } }

}

int main(){ int ca=1; memset(dp,false,sizeof(dp)); is_prime();//打表 while(scanf("%d",&n)!=EOF){ printf("Case %d:\n",ca); memset(isvisited,false,sizeof(isvisited)); m[1]=1;//题目要求第一个必须是1 dfs(1);//所以我们已经先有一个了,然后向下搜索 ca++; printf("\n");//注意输出完毕以后还有一个空行 } return 0; }