题目描述:
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
求解:
用回溯法求解。其中判断素数的结果先保存起来。
// Prime Ring Problem
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 20
int isPrime[2*N]; //保证是否为素数,0表示不是,1表示是
int arr[N]; //存放结果
int visit[N]; //表示数字i有没有被用过
//对素数的结果进行初始化
void initPrime(){
int i,j;
isPrime[0]=0;
isPrime[1]=0;
for(i=2;i<2*N;i++){
isPrime[i]=1;
for(j=2;j<=sqrt(i);j++){
if(i%j==0){
isPrime[i]=0;
break;
}
}
}
}
//深度优先,回溯法
void dfs(int n,int index){ //index代表第index位
int i;
if(index==n && isPrime[arr[0]+arr[n-1]]==1 ){
for(i=0;i<n-1;i++){
printf("%d ",arr[i]);
}
printf("%d\n",arr[i]);
}else{
for(i=2;i<=n;i++){
if(visit[i]==0 && isPrime[i+arr[index-1]]==1){
arr[index]=i;
visit[i]=1;
dfs(n,index+1);
visit[i]=0;
}
}
}
}
int main(){
initPrime();
int n,ca=1;
while(~scanf("%d",&n)){
int i;
memset(visit,0,sizeof(visit));
arr[0]=1; //结果数组的第0位肯定是1
printf("Case %d:\n",ca++);
dfs(n,1);
printf("\n");
}
return 0;
}