zoukankan      html  css  js  c++  java
  • 质数环

    输入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
    ",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("
    ");
    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
    ",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("
    ");
    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
  • 相关阅读:
    项目中遇到的问题:前台 disabled 与 后台disabled
    差距
    那些零碎的感悟,那些成长的事【壹】
    假期数据结构学习总结
    烟大 2242: 回文(栈和队列)
    烟大 2241: 相同序列(栈和队列)
    烟大 2239: 十进制与八进制的转换(栈和队列)
    烟大 2238: 括号匹配(栈和队列)
    hdu 1018:Big Number(水题)
    hdu 2050:折线分割平面(水题,递归)
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/4747009.html
Copyright © 2011-2022 走看看