题目描述
给定 2 个整数 a, b 求出它们之间包括(a, b)的所有质数的和。
输入格式
两个整数 a, b (1 ≤ a, b ≤ 105)。
输出格式
一个整数,表示范围内的质数和。
Sample Input
999 10
Sample Output
76110
思路
先判断一个数是否为质数,然后将质数求和。
那么如何判断一个数是否为质数呢?
方法①:从 2 到 n 循环一遍,看看有没有能除尽 n 的,如果有, 那这个数不是质数,如果没有,那么这个数是质数。
方法②:从 2 到 √n 循环一遍,看看有没有能除尽 n 的,如果有, 那这个数不是质数,如果没有,那么这个数是质数。也就是方法①的进化版,这个算法可以缩短程序的运行时间,降低时间复杂度。
方法③:线性筛。思想是:从 2 开始,因为 2 的倍数一定不是素数,所以先把2的倍数全部删去;接着找下一个素数3,把3的倍数全部删去;因为4是2的倍数,已经被删去,所以直接找下一个素数5,把5的倍数全部删去;接着7的倍数,11的倍数,…直到把某个范围内的合数全部筛选出去,剩下的即为素数。
方法④:六倍原理。可以从数学上证明,大于6的质数都是在6 的倍数的左右两边。
C语言代码:
#include<stdio.h>
#include<math.h>
int isprime(int x)
{
if(x <= 1) return 0;
for(int i = 2; i <= sqrt(x); i++)
if(x % i == 0) return 0;
return 1;
}
int main()
{
int a, b, sum = 0;
scanf("%d %d", &a, &b);
if(a > b)
{
int c = b;
b = a;
a = c;
}
for(int i = a; i <= b; i++)
if(isprime(i))
sum += i;
printf("%d\n",sum);
return 0;
}
#include<stdio.h>
#include<string.h>
#define maxn 1000000 + 10
int vis[maxn];
void isprime()
{
memset(vis, 0, sizeof(vis)); //此处vis[i]=1表示不是素数,vis[i]=0表示是素数
vis[1] = 1; //由于i * i的数据范围可能会超过int,所以需要用long long表示
for(long long i = 2; i * i <= maxn; i++)//此处有优化,因为如果一个合数 > sqrt(maxn),那么它必定在前面已经被标记过。
if(!vis[i])
for(long long j = i * i; j <= maxn; j += i)//此处也有优化,我们只需要判断从i*i开始判断即可。
vis[j] = 1;
}
int main()
{
ios::sync_with_stdio(false);
isprime();
int x, y;
while(cin >> x >> y)
{
if(x == 0 && y == 0) break;
int flag = 0;
for(int i = x; i <= y; i++)
if(vis[i * i + i + 41])
flag = 1;
flag == 1 ? cout << "Sorry" << endl : cout << "OK" << endl;
}
return 0;
}
C++代码:
#include<bits/stdc++.h>
using namespace std;
bool is_prime(int n)
{
for(int i = 2; i * i <= n; i++)
if(n % i == 0)
return false;
return true;
}
int main()
{
int a, b, t;
while(cin >> a >> b)
{
int sum = 0;
if(a > b)
{
t = a;
a = b;
b = t;
}
if(a == 1) a = 2;
for(int i = a; i <= b; i++)
if(is_prime(i)) sum += i;
cout << sum << endl;
}
return 0;
}
//欧拉筛
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5;
const long long M = 1e5;
int pr[M + 10], vis[M + 10], t;
void ispr()
{
vis[0] = 1; vis[1] = 1; vis[2] = 0;
for(int i = 2;i <= M; i ++)
{
if(!vis[i]) pr[++t] = i;
for(int j = 1;j <= t && i * pr[j] <= M;j ++)
{
vis[i * pr[j]] = 1;
if(i % pr[j] == 0) break;
}
}
}
void sol()
{
int a, b;
cin >> a >> b;
long long sum = 0;
if(a > b)
{
int mid = a;
a = b;
b = mid;
}
for(int i = a;i <=b;i ++)
if(!vis[i])sum += i;
cout << sum;
}
int main()
{
ispr();
sol();
return 0;
}
#include<iostream>
#include<cmath>
using namespace std;
bool check(int n)
{
if(n == 1) return false;
if(n == 2 || n == 3) return true;
if(n % 6 != 5 && n % 6 != 1) return false;
for(int i = 5; i <= sqrt(n); i += 6)
if(n % i == 0 || n % (i + 2) == 0)
return false;
return true;
}
int main()
{
int a, b, sum = 0;
cin >> a >> b;
int min = a;
if(a > b) min = b;
for(int i = min; i <= a + b - min; ++i)
if(check(i))
sum += i;
cout << sum << endl;
return 0;
}