蒜头君的猜想 - 计蒜客

有一天蒜头君突发奇想,他有一个猜想,任意一个大于 2 2 的偶数好像总能写成 2 2 个质数的和。

蒜头君查了资料,发现这个猜想很早就被一个叫哥德巴赫的人提出来了,称为哥德巴赫猜想。

目前还没有证明这个猜想的正确性。

蒜头君告诉你一个整数 n n ,让你用这个数去验证。

注意 1 1 不是质数。

输入格式

输入一个偶数 n ( 2 < n 8000000 ) n(2 < n \le 8000000)

输出格式

输出一个整数表示有多少对 ( x , y ) (x,y) 满足 x + y = n ( x y ) x + y = n(x \le y) x , y x,y 均为质数。

样例输入

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;
		  }
		}
	}

然后在该数组内寻找,相加为 n n 的质数。
1.用双层for循环一个个去匹配效率很低,OJ里也会超时。
2.参考皮卡丘的思路后发现,可以只用一个for循环,且只需判断数组内的下标为 i i n i n-i 的元素,既完成了对该两个元素是否同时是质数的判断,又将两数相加是否为 n n 一并判断。
功能实现如下:

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;
}

猜你喜欢

转载自blog.csdn.net/qq_43508196/article/details/86661176