题意:
一个环有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(" "); 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: ",count++); 59 if(n == 1) 60 printf("1 "); 61 for(int i=2; i<=n; i++) 62 dfs(1, i, 2); 63 printf(" "); 64 } 65 return 0; 66 }