求n以内最大的k个素数以及它们的和
一、题目描述
本题要求计算并输出不超过n的最大的k个素数以及它们的和。
输入格式:
输入在一行中给出n(10≤n≤10000)和k(1≤k≤10)的值。
输出格式:
在一行中按下列格式输出:
素数1+素数2+…+素数k=总和值
其中素数按递减顺序输出。若n以内不够k个素数,则按实际个数输出。
输入样例1:
1000 10
输出样例1:
997+991+983+977+971+967+953+947+941+937=9664
输入样例2:
12 6
输出样例2:
11+7+5+3+2=28
二、解题思路
根据题目描述,预想可能需要的变量如下
1.输入的变量n,k,题目要求会不断遍历小于等于n的整数,去找最大的k个素数并求和;
如果不足k个,打印到最小的素数2求和。
2.题目涉及到打印有限个素数,所以可能需要一个变量count来计数,初值为0。
3.而且涉及到求和,所以需要一个变量sum,初值为0.
所以上述过程写成代码是:
int n,k;
scanf("%d%d",&n,&k);
int count=0;
int sum=0;
for(int i=n;i>1;i--){...
}
在这个for循环里面,i 代表一个个要检验的数,我们要检验 i 是否为素数,那怎么检验呢?
这需要一个for循环,首先定义一个变量flag用来标记这个是是素数还是合数,素数为1,合数为0
int flag=1;//用来记录是否是素数,一开始默认都是素数,flag等于1表示这个数是素数
for(int j=2;j<=i/2;j++){ //j从2~i/2(可能有因子的区间)if(i%j==0){ //看一下i能不能被其中的一个j整除,如果能,说明这个区域有一因子flag=0; //将flag置为0,表示这是一个合数break; //只要有一个因子,就可以判断出来是合数了,不需要继续往下除了,结束这个循环}
}
如果是素数if(flag==1),我们要怎么办呢?直接输出吗?
题目非常重要的点就是打印有限个素数,这里就要开始根据题目要求来设想什么情况下我们素数才算是打印完了
- 根据测试样例1,当count等于k的时候,素数打印完成求和
- 根据测试样例2,当遍历小于等于n的整数,这个整数等于2的时候,素数打印完成求和
在这里需要多一点观察
997+991+983+977+971+967+953+947+941+937=9664
我们打印完素数之后紧接着打印一个“+”号,
但不是所有的素数后面都跟着+号,
比如最后一个素数,她后面跟着的是=,所以我们要考虑一下什么情况下打印最后一个素数
- 根据测试样例1,当count等于k-1的时候,就准备开始打印最后一个素数了
- 根据测试样例2,当遍历小于等于n的整数 i ,这个整数 i 等于2的时候,就准备开始打印最后一个素数了
打印完最后一个素数的时候,可以顺带打印算式末尾的等号=以及所有的素数和sum,并跳出循环
if(flag==1){ //已经确定当前i是素数了if(count==k-1 || i==2){ //前面k-1个素数已经打印完了,或者当前数字i已经到绝境素数2了sum+=i; //求一下最后一个素数的累加和printf("%d=%d",i,sum); //打印最后一个素数=sumbreak; }else if(count<k-1){ //当count小于k-1,也就是还没有打印完前面k-1个素数且i还没到绝境2printf("%d+",i);count++; //打印完计数+1sum+=i; //顺带求和}
}
三、完整代码
整合一下上面的代码
#include<stdio.h>
int main(){int n,k;scanf("%d%d",&n,&k);int count=0;int sum=0;for(int i=n;i>1;i--){//用来记录是否是素数,每换一个数更新为1int flag=1;for(int j=2;j<=i/2;j++){if(i%j==0){flag=0;break;}}//已经确定当前i是素数了if(flag==1){ //前面k-1个素数已经打印完了,或者当前数字i已经到绝境素数2了if(count==k-1 || i==2){ sum+=i; //求一下最后一个素数的累加和printf("%d=%d",i,sum); //打印最后一个素数=sumbreak; }else if(count<k-1){ //当count小于k-1,也就是还没有打印完前面k-1个素数且i还没到绝境2printf("%d+",i);count++; //打印完计数+1sum+=i; //顺带求和}} }return 0;
}