题意:

一个环有n个点,将1-n填入这些点中,要求相邻两个点和为素数。输入n,输出所有可能的填法。

题意:利用dfs对n个数进行全排列,有符合题意的排列则输出。

 1 #include <stdio.h>
 2 
 3 int num[21];     //num数组存储的是数字的存储顺序 
 4 int mark[21];    //mark数组是为了标记某个数字是否使用过,用过为0,没用过为1 
 5 int n;    //共n个数     
 6 //列出在题目规定范围内(0<n<20)所有可能出现的质数 
 7 int prime_num[12] = {2,3,5,7,11,13,17,19,23,29,31,37};
 8 
 9 //判断是否是质数,是返回1,不是返回0
10 int is_prime(int a)
11 {
12     for(int i = 0; i < 12;i++)
13         if(a == prime_num[i])
14                 return 1;
15     return 0;
16 }
17 
18 void print_num()    //打印从num[1]到num[n] 
19 {
20     for(int i=1; i<n; i++)
21         printf("%d ",num[i]);
22     printf("%d",num[n]);
23 }
24 //深度优先搜索 ,pre和post表示搜索到的两个相邻的数
25 // flag表示搜索的深度,flag==n时结束 
26 int dfs(int pre, int post, int flag)    
27 {    
28 //如果相邻两个数相加不是素数,直接返回    
29     if( !is_prime(pre+post) )
30         return 0;    
31     num[flag] = post;
32     if(flag==n && is_prime(post+1))
33     {
34         print_num();
35         printf("\n");
36         return 1;
37     }
38     //使用过了这个数字就标记为0
39     mark[post] = 0;
40     //遍历查找没有被用过的数 
41     for(int i=2; i<=n; i++)
42         if(mark[i]!=0 && dfs(post,i,flag+1))
43                 break;
44     //标记位恢复原状
45     mark[post] = 1;
46     return 0;
47 }
48 
49 int main() 
50 {
51         //输出答案的次数 
52     int count = 1;
53     while(scanf("%d",&n) != EOF)
54     {
55         for(int i=1; i<=n; i++)
56             mark[i] = 1;
57         num[1] = 1;
58         printf("Case %d:\n",count++);
59         if(n == 1)
60                     printf("1\n");
61         for(int i=2; i<=n; i++)
62             dfs(1, i, 2);
63         printf("\n");
64     }
65     return 0;
66 }