有一天蒜头君突发奇想,他有一个猜想,任意一个大于 的偶数好像总能写成 个质数的和。
蒜头君查了资料,发现这个猜想很早就被一个叫哥德巴赫的人提出来了,称为哥德巴赫猜想。
目前还没有证明这个猜想的正确性。
蒜头君告诉你一个整数 ,让你用这个数去验证。
注意 不是质数。
输入格式
输入一个偶数
输出格式
输出一个整数表示有多少对 满足 且 均为质数。
样例输入
6
样例输出
1
样例输入
10
样例输出
2
解:
先用下面的代码生成一个数组,下标表示数,元素只有1与0,表示是否质数。
is_prime.push_back(0);//0
is_prime.push_back(0);//1
for (int i = 2; i <= n; ++i) {
is_prime.push_back(1);
}
for (int i = 2; i * i <= n; ++i) {
if (is_prime[i]) {
for (int j = i * i; j <= n; j +=i) {
is_prime[j] = 0;
}
}
}
然后在该数组内寻找,相加为
的质数。
1.用双层for循环一个个去匹配效率很低,OJ里也会超时。
2.参考皮卡丘的思路后发现,可以只用一个for循环,且只需判断数组内的下标为
与
的元素,既完成了对该两个元素是否同时是质数的判断,又将两数相加是否为
一并判断。
功能实现如下:
for(int i=2;i<=n/2+1;i++){
if(is_prime[i]&&is_prime[n-i])//简化寻找匹配的质数
flag++;
}
完整代码:
#include"iostream"
#include"vector"
#include"algorithm"
using namespace std;
int main()
{
int n,flag=0;
vector<int>is_prime;
scanf("%d",&n);
//筛选质数
is_prime.push_back(0);
is_prime.push_back(0);
for (int i = 2; i <= n; ++i) {
is_prime.push_back(1);
}
for (int i = 2; i * i <= n; ++i) {
if (is_prime[i]) {
for (int j = i * i; j <= n; j +=i) {
is_prime[j] = 0;
}
}
}
for(int i=2;i<=n/2+1;i++){
if(is_prime[i]&&is_prime[n-i])//简化寻找匹配的质数
flag++;
}
printf("%d",flag);
return 0;
}