蓝桥杯C语言练习题目(十)---- 等差素数

一、题目要求如下:

二、解题思路

        我想到的是暴力枚举,即列举出一定数量的、足够多的可能性,直接暴力枚举出所有情况;

        题目要求是:

                1、求10个素数组成的等差数列

                2、等差数列的公差要求是最小的

这里首先需要先提前定义一个判断是否为素数的函数。

素数的条件是:

        1、除了1和这个数本身,不能被其他数整除

        2、0不是素数

例如:2、3、5、7这些数字都只能被1或者被它本身整除。其他任何数字除都不能除尽。

求素数的函数定义如下:

 为什么要用到sqrt呢?

sqrt()是数学函数库中的求根函数,要使用的话得在包含头文件的位置声明包含<math.h>

sqrt()是求平方根的函数,例如:sqrt(9)=3;

而一个数字如果除以小于自身的平方根的整数都不能除尽,说明后面的数字就没有意义再求了。这样能大大减少程序的时间复杂度。

其实也可以不用,直接i<n也行,但是这样的运行时间会多很多。

num()函数可以求当前数字是否是素数,是就返回1,不是就返回0;

例:num(5)=1;num(4)=0;

我们需要得到一个等差数列,而等差数列就是一个递增或者递减的数列,其中每个数字的差值都是相同的,这个差值我们称之为公差。例如:1、3、5、7、9就是一个等差数列,公差为1;

而这个等差数列中的第一个数字称为第一项

所以我们用两个循环,分别枚举出大量的第一项素数和大量的公差。

并且对每个第一项都重复全部公差,看看能否有那么一个公差能累加出10个等差素数。

第一层循环i:列举第一项

第二层循环j:列举这个项的公差

第三层while循环:累加公差,若超过10个或者加到的下一个数字不是素数的时候跳出来这层循环

主要框架:

for(列举从2~n,每个都是第一项){

        for(列举从2~n,每个都是一个公差){

                while(当前项+公差是否为素数){是素数就累加公差;并且记录下来有多少个等差项了;如果超过了10个就跳出循环;}

                if(刚好10个等差素数){跳出循环;}

        }

         if(刚好10个等差素数){跳出循环;}

}

三、代码实现

#include <stdio.h>
#include <math.h>

//判断是否是素数
bool num(int n){
  int i;
  if(n==1||n==0){
    //printf("不是素数\n");
    return 0;
  }

  for(i=2;i<sqrt(n);i++){
    if(n%i==0) {//printf("不是素数\n");
      return 0;
    }
  }
  return 1;
}


int main()
{
  // i为枚举出来的数字,不一定为素数
  // j为枚举出来的公差,每个i都执行2-50000的方差,看看下一个数字是否为素数
  // k为存储i的临时变量,因为在累加10个素数等差数列的时候需要重复加公差,不能影响i的值,否则影响枚举数字的这层循环
    int i,j,k,n=1;
    //枚举数字2-50000
    for(i=2;i<50000;i++){
      if(num(i)){//如果i为素数
        k=i;//k为临时变量存储i

        //第二层循环枚举2-50000的方差。每次都将第一个素数+方差,看看是否还是素数,当累计到10个即满足题目要求
        for(j=2;j<50000;j++){
          k=i;//重置k,为什么要这个呢?因为当出现n>10的情况,就是说数列可能不止10个的情况,或者没到10个就退出来的情况,需要重置k值为i,不然就一直累加下去了
          while(num(k+j)){//若k+j为素数。k=i,而i是枚举的素数
            k+=j;//k累加方差
            n+=1;//n为该数列长度。即:当下包含多少个等差素数了
            if(n>10) break;//当n>10时,意味着当前素数的当前等差值中,出现了不止10个的等差素数。题目要求是10个,不能是11个或以上
          }
          //执行到该行说明已经遍历完了一个等差素数数列,该等差数列个数满足n>=10,所以要判断是否是10个,是的话跳出循环,不是继续找
          if(n==10) break;
          n=1;//重置数列个数
          
        }
        //这个也是必须的,不然这层循环跳不出去
        if(n==10) break;
      }
    }
    printf("%d",j);
  return 0;
}

-----------------------------------------------------------------------------------

码题不易,跪求点赞!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值