A ring is composed of n (even number) circles as shown in diagram. Put natural numbers 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 ≤ 16)
Output T he 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. You are to write a program that completes above process.
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
分析: dfs回溯,判断两数和是否为素数以及是否重复使用作为剪枝条件。
Source:
#include<stdio.h> #include<string.h> int vis[20]; int ans[20]; int n; int is_prim(int x) /*判断是否为素数*/ { int i; if(x<=2) /*首尾两位不能同时为1*/ return 0; for(i=2;i<x;i++) if(x%i==0) { return 0; break; } if(i==x) return 1; } void dfs(int cur) /*回溯*/ { int i; if(cur==n&&is_prim(1+ans[n-1])) { for(i=0;i<n-1;i++) printf("%d ",ans[i]); printf("%d\n",ans[n-1]); /*注意输出格式*/ } else { for(i=2;i<=n;i++) { if(!vis[i]&&is_prim(i+ans[cur-1])) /*剪枝条件*/ { vis[i]=1; /*标记*/ ans[cur]=i; dfs(cur+1); /*搜索下一位*/ vis[i]=0; /*取消标记*/ } } } } int main() { int t=0; while(scanf("%d",&n)!=EOF) { t++; if(t>=2) /*注意输出格式*/ printf("\n"); memset(vis,0,sizeof(vis)); ans[0]=1; printf("Case %d:\n",t); dfs(1); /*注意搜索起点*/ } return 0; }