赞
踩
题目作者:张彤彧 浙江大学
本题要求统计给定整数M和N区间内素数的个数并对它们求和。
输入在一行中给出两个正整数M和N(1≤M≤N≤500)。
在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。
10 31
7 143
思路1:这里是要统计[M,N]闭区间内所有素数的个数和它们的和。我们用两层循环,外层循环枚举出所有正整数i,M<=i<=N;用里层循环判断i是不是素数,若是素数就给计个数加1,和加i;若不是素数,就继续外层循环。
要判断出一个正整数是不是素数,这就是素数判定问题。根据素数的定义,一个大于等于2的正整数p,如果它只能被1和p本身整除,那么p是素数。于是我们用最原始的办法,用循环枚举出所有的正整数j,2<=j<=p-1;若某一个j能整除p,即p%j==0, 那么我们就可以标记p为合数,然后跳出循环(因为后面的遍历是没有意义的);若直到循环结束都p都没有被标记为合数,说明p确实没有1和p本身以外的其他因子,即p是素数。当然这里可以做一个简单的优化,可以不用枚举2到p-1之间的所有正整数,只需要枚举2到sqrt(p)之间的所有正整数即可。
注意:对1要单独处理,显然1也是只能被1和它本身整除的正整数,所以如果遇到1,我们不要用循环去判断它,直接跳过。在一个循环里,要跳过循环体后面所有的代码,并执行下一轮循环,用continue语句。
- #include <stdio.h>
- #include <math.h>
- int main () {
- int M,N,i,j,cnt=0,sum=0,flag = 1;
- scanf("%d%d", &M, &N);
- for (i = M; i <= N; i++) {
- flag = 1;
- if (i == 1) continue; // 注意,这里对i==1的情况要单独处理
- for (j = 2; j <= sqrt(i); j++) {
- if (i%j == 0) {
- flag = 0;
- break;
- }
- }
- if (flag) {
- cnt++;
- sum += i;
- }
- }
- printf("%d %d", cnt, sum);
- return 0;
- }
我们还可以把判定素数的代码封装成一个函数,得到如下的代码:
- #include <stdio.h>
- int isPrime (int P) { //定义一个函数,用来判断一个数P是不是素数,是返回1,不是返回0
- int i, flag = 1;
- for (i = 2; i <= sqrt(P); i++) {
- if (P%i == 0) {
- flag = 0;
- break;
- }
- }
- return (P <= 1) ? 0 : flag;
- }
- int main () {
- int i,M,N,cnt=0,sum=0;
- scanf("%d%d", &M, &N);
- for (i = M; i <= N; i++) {
- if(isPrime(i)) {
- cnt++;
- sum+=i;
- }
- }
- printf("%d %d", cnt, sum);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。