质数环

输入N,将1~N这N个整数摆成一个环,使得任意相邻两个数之和都是质数。

分析:

递归,回溯

算法的流程:递归填数:判断第i个数填入是否合法。

若是合法:填数,判断是否到达目标(填入20个数字),是则打印结果,否则递归进入下一层填写下一个数字。

若是不合法:选择下一种可能进行尝试。

代码如下:(不足之处在于:这里输出的环可能本质是相同的,也就是会有重复。如何改进请看代码二)

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 int N;
 5 int b[21]={0};
 6 int total=0,a[21]={0};
 7 int search(int);        //回溯过程
 8 int print();            //输出方案
 9 int pd(int x,int y);    //判断素数x+y是否质数
10 
11 int main()
12 {
13     scanf("%d",&N);
14     search(1);
15     printf("%d\n",total);                    //输出总方案数
16 }
17 int search(int t)
18 {
19     int i;
20     for(i=1;i<=N;i++)           //有20个数可选
21      if((!b[i])&&pd(a[t-1],i))  //判断与前一个数是否构成素数及该数是否可用
22      {
23          a[t]=i;
24          b[i]=1;
25          if (t==N) { if(pd(a[N],a[1])==1) print();}
26          else search(t+1);
27          b[i]=0;
28      }
29 }
30 int print()
31 {
32    int j;
33    total++;
34    printf("<%d>",total);
35    for(j=1;j<=N;j++)
36        printf("%d ",a[j]);
37    printf("\n");
38 }
39 int pd(int x,int y)
40 {
41     int k=2,i=x+y;
42     while(k<=sqrt(i)&&i%k!=0) k++;
43     if(k>sqrt(i)) return 1;
44     else return 0;
45 }

想要去除重复的环,只需要固定环中的某一个位置取某一个值就行。比如:规定环的第一个元素取1.当然,这样规定后,以后每一次递归回溯选择的时候都不能选2了,所以,search函数里面,for循环的起始值为2.

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 int N;
 5 int b[21]={0};
 6 int total=0,a[21]={0};
 7 int search(int);        //回溯过程
 8 int print();            //输出方案
 9 int pd(int x,int y);    //判断素数x+y是否质数
10 
11 int main()
12 {
13     scanf("%d",&N);
14     a[1]=1;
15     search(2);
16     printf("%d\n",total);                    //输出总方案数
17 }
18 int search(int t)
19 {
20     int i;
21     for(i=2;i<=N;i++)           //有20个数可选
22      if((!b[i])&&pd(a[t-1],i))  //判断与前一个数是否构成素数及该数是否可用
23      {
24          a[t]=i;
25          b[i]=1;
26          if (t==N) { if(pd(a[N],a[1])==1) print();}
27          else search(t+1);
28          b[i]=0;
29      }
30 }
31 int print()
32 {
33    int j;
34    total++;
35    printf("<%d>",total);
36    for(j=1;j<=N;j++)
37        printf("%d ",a[j]);
38    printf("\n");
39 }
40 int pd(int x,int y)
41 {
42     int k=2,i=x+y;
43     while(k<=sqrt(i)&&i%k!=0) k++;
44     if(k>sqrt(i)) return 1;
45     else return 0;
46 }
View Code

 

posted on 2015-08-21 10:05  华山青竹  阅读(656)  评论(0编辑  收藏  举报

导航