题目链接
题目描述
输入一个偶数 N,验证 4∼N 所有偶数是否符合哥德巴赫猜想:任一大于 2 的偶数都可写成两个质数之和。如果一个数不止一种分法,则输出第一个加数相比其他分法最小的方案。例如 10,10=3+7=5+5,则 10=5+5是错误答案。
输入格式
第一行输入一个正偶数 N
输出格式
输出2N−2 行。对于第 i 行:
首先先输出正偶数 2i+2,然后输出等号,再输出加和为 2i+2 且第一个加数最小的两个质数,以加号隔开。
输入输出样例
输入
10
输出
4=2+2 6=3+3 8=3+5 10=3+7
说明/提示
数据保证,4 ≤ N ≤ 10000。
思路分析
这道题是把有限个偶数表示成两个质数的和,且第一个质数为比其他分法的质数都要小。所以这道题有两个主要工作—1:找出一个偶数所能表示成的两个加数都是质数的情况;2:找到可表示成加数的质数中最小的质数。既然题目要求我们求4~N的每个偶数的质数和,那么为了避免每次求一个偶数时都要去求该加数是否为质数,我们干脆在一开始就把范围内所有质数都求出来,但是那会不会有无穷个呢,这时候我们就要注意一下题目的说明提示了,题目说N<=10000,所以这个数据量时OK的,求某范围内的质数方法有很多种,详细的可以看这位博主写的,https://blog.csdn.net/qq_41939020/article/details/99167166
我采用的是第五种较快的算法。然后在求出所有质数后,还要找出可表示的加数的质数中最小的质数,所以我们在遍历每一个加数去求它的质数时,直接从最小的质数开始找起,那么我们刚刚已经求得2~10000内所有质数,但它们是乱序的,那么推荐大家用C++自带的set容器 ,这道题可以应用到set容器的两个特性,1:set容器里的元素不重复而且是有序排列的,默认降序;2:set容器里的元素可以用find()去访问是否存在,不用遍历,减少了我们在判断一个加数是否是质数时的时间复杂度。详细的set用法这位博主的文章有详细介绍https://blog.csdn.net/xj470574/article/details/122622361
不要忘记除了找出小的质数,还要判断另一个加数是否为质数(这里就可以直接用set的find()属性)。
代码贴这
#include<iostream>
#include<set>
int a[10000] = { 0 };
using namespace std;
int main()
{
//将2到10000的素数全部找出并存放在set容器中
set<int> prime;//创建一个存放素数的set容器
for (int i = 2; i < 10000; i++)
{
if (!a[i])
{
prime.insert(i);
for (int j = i * 2; j < 10000; j += i)
{
a[j] = 1;
}
}
}
int n;
cin>>n;
//开始遍历每一个4~N的偶数
for(int i=4;i<=n;i+=2)
{
//对于每个偶数的第一个加数,从set容器中小的质数开始遍历
for(set<int>::iterator it=prime.begin();it!=prime.end();it++)
{
//对于每一个小质数,确认与之对应的另一个加数是否也为质数
if(prime.find(i-(*it))!=prime.end())
{
cout<<i<<"="<<(*it)<<"+"<<i-(*it)<<endl;
break;
}
}
}
return 0;
}
有什么可以改进的地方大家多多指教咯☺