目录
本题要求统计给定整数M和N区间内素数的个数并对它们求和。
输入格式:
输入在一行中给出两个正整数M和N(1≤M≤N≤500)。
输出格式:
在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。
输入样例:
10 31
输出样例:
7 143
通过代码:
#include<stdio.h>
#include<math.h>
int prime(int x);
int main(){
int M,N;
scanf("%d %d", &M,&N);
int count=0,sum=0;
for (int i=M;i<=N;i++){
if (prime(i)){
sum += i;
count++;
}
}
printf("%d %d", count,sum);
return 0;
}
int prime(int x){
if (x==1) return 0;
for (int i=2; i<=sqrt(x); i++)
if (x%i==0)
return 0;
return 1;
}
零基础详解:
整个程序的编写思路为:
- 找出M和N之间的所有的数。
- 判断是否满足条件(是素数)。
- 记录满足条件的数的个数以及这些数的和。
1. 基本框架
在上一篇关于输入输出的内容里,有提到过关于基本框架的事情,在此对基本框架的内容进行一些完善,具体如下:
#include <stdio.h>
int main()
{
int M, N; //定义需要用到的变量
int count = 0, sum = 0; //变量的初始化
scanf("%d %d", &M, &N); //需要输入的变量
/*函数的主体*/
printf("%d %d", count, sum); //需要输出的变量
return 0;
}
对于大多数的问题都有着自己的输入和输出。因此我们在搭建函数框架的时候,可以先将输入和输出的部分全部搞好,剩下我们只用关心变量之间的运算即可。
2. 找到从M到N之间所有的数【for
】
类似这种已知起点
和终点
要找出在起点和终点之间满足某些规律的数,用for
循环是一种比较简单的方法,使用方式为:for(exp1;exp2;exp3)
后加Loopbody
,其中:
exp1
用于给Loopbody
中的变量赋予初值exp2
用于判定是否执行Loopbody
的语句【非0时执行】exp3
用于在每次执行Loopbody
之后修改变量的值Loopbody
为每次循环中需要执行的语句
以遍历M到N之间所有的数为例,具体使用方法如下:
#include <stdio.h>
int main()
{
int M, N;
int count = 0, sum = 0;
scanf("%d %d", &M, &N);
int i; //定义循环变量i
for (i = M; i <= N; i++){
/*这里边的内容被称为Loopbody*/
}
//也可以在for循环中定义变量,如:for (int i = M; i <= N; i++)
printf("%d %d", count, sum);
return 0;
}
其中:
i = M
:表示i
从M
开始i <= N
:表示在i <= N
的时候执行Loopbody
的内容i++
:表明每次执行完Loopbody
的内容后执行语句i++
这样可以保证i
取到从M
到N
的所有的值
3 进行判定【if
】
在编写程序的过程中,我们常常需要达到类似“如果xxx”,“就xxx”的效果。而if
函数可以实现这样的效果。if
函数的使用方法为:if(exp)
后加sentence
,其中:
exp
表示判定sentence
是否运行的语句【0
不运行,非0
运行】sentence
表示如果exp
为真需要执行的语句
在此题中,我们需要对所有的i
进行判定,判断这个i
是否为素数,具体代码如下:
#include <stdio.h>
int main()
{
int M, N;
int count = 0, sum = 0;
scanf("%d %d", &M, &N);
int i;
for (i = M; i <= N; i++){
//利用if判定那个数(i)是否是质数
if (prime(i)){ //如果i是质数prime(i)=1,否则prime(i)=0
/*这里输入stence*/
}
}
printf("%d %d", count, sum);
return 0;
}
4.1 函数的调用
由于C语言内置的函数中并不包括prime
,所以我们需要自己编写和调用prime
函数。在调用函数之前,我们需要先定义和声明函数,具体方法为
- 函数的定义:
函数类型 函数名称( 变量类型 变量名称)
后接函数体
- 函数的声明:
函数类型 函数名称( 变量类型 变量名称);
在使用前声明
以prime
函数为例,具体代码如下:
#include <stdio.h>
int prime(int x); //prime函数的声明
int main()
{
int M, N;
int count = 0, sum = 0;
scanf("%d %d", &M, &N);
int i;
for (i = M; i <= N; i++){
if (prime(i)){
/*这里输入sentence*/
}
}
printf("%d %d", count, sum);
return 0;
}
int prime(int x) //prime函数的定义
{
/*这里输入函数体*/
}
prime
函数只能是0或者1,所以函数类型为int
prime
函数的作用是判断一个自然数x
是否为质数,所以输入的参数类型为int
4.2 判定素数函数【prime
】
- 素数:一个数,他只能被1和他本身整除。
注:1既不是素数也不是合数
因此编写的思路为:判断一个数x
是否是质数,只需要对从2
到x-1
的所有的数取余数%
,如果存在余数为0
的情况,则说明x
不是质数。【稍微优化一下可以只对2
到sqrt(x)
取余数即可】
为什么是
x
\sqrt{x}
x 证明如下:
若
x
x
x不是质数,也就是说
∀
m
,
n
→
x
=
m
×
n
\forall m,n \rightarrow x = m \times n
∀m,n→x=m×n
且假设
m
≤
n
m\leq n
m≤n:两个数,总有一个小于等于另外一个,则必有:
m
≤
x
≤
n
m \leq \sqrt{x} \leq n
m≤x≤n
反证法可知,若
m
,
n
<
x
m,n < \sqrt{x}
m,n<x, 那么
m
×
n
<
x
m \times n < x
m×n<x【大于同理】
故,如果
x
x
x不是质数,那么必定存在一个
x
x
x的因数
m
≤
x
m \leq \sqrt{x}
m≤x
根据上述原理我们可以编写如下程序:
int prime(int x){ //质数判定函数
if (x==1) //如果x为1,那么x不是质数,返回0
return 0;
//如果x大于等于2,开始遍历
for (int i=2; i<=sqrt(x); i++) //从2到sqrt(x) 上边解释了
if (x%i==0) //如果存在余数为0的情况
return 0; //返回0
return 1; //如果运行完所有的都不存在,则返回1
}
5. 计数和求和
统计满足某些条件的数的个数,以及对某些数进行累加,是C程序中很常见的小技巧。通常我们让求和的结果为sum
,用count
来记录个数。
只需要在满足条件的语句(即if
后的sentence
)中增加:
sum += i;
表示每当满足条件的时候sum
再原本的基础上加上i
count++;
表示每当满足条件的时候count
的值增加1
在题目中具体的代码样例如下:
#include<stdio.h>
#include<math.h> //当使用sqrt函数的需要调用<math.h>
int prime(int x);
int main(){
int M,N;
scanf("%d %d", &M,&N);
int count=0,sum=0;
for (int i=M;i<=N;i++){
if (prime(i)){ //如果i是素数
sum += i; //sum在原本的值上+i
count++; //count的数量+1
}
}
printf("%d %d", count,sum);
return 0;
}
int prime(int x){
if (x==1) return 0;
for (int i=2; i<=sqrt(x); i++)
if (x%i==0)
return 0;
return 1;
}