题目描述
输入一个偶数 N N N,验证 4 ∼ N 4\sim N 4∼N 所有偶数是否符合哥德巴赫猜想:任一大于 2 2 2 的偶数都可写成两个质数之和。如果一个数不止一种分法,则输出第一个加数相比其他分法最小的方案。例如 10 10 10, 10 = 3 + 7 = 5 + 5 10=3+7=5+5 10=3+7=5+5,则 10 = 5 + 5 10=5+5 10=5+5 是错误答案。
输入格式
第一行输入一个正偶数 N N N
输出格式
输出 N − 2 2 \dfrac{N-2}{2} 2N−2 行。对于第 i i i 行:
首先先输出正偶数 2 i + 2 2i+2 2i+2,然后输出等号,再输出加和为 2 i + 2 2i+2 2i+2 且第一个加数最小的两个质数,以加号隔开。
样例 #1
样例输入 #1
10
样例输出 #1
4=2+2
6=3+3
8=3+5
10=3+7
提示
数据保证,$ 4 \leq N\leq10000$。
1.题目分析
输入一个偶数,代表右边界,从4到有边界遍历每一个偶数,输出每一个偶数的两个质数之和,保证左边的质数最小化。
说一下质数的判断方法:不能够被1以外的任何自身的因子整除。
2.题目思路
写一个判断质数的函数,输入N,写一个数组存储N以内的所有质数,
用一个三层循环,第一层代表4到N的偶数,第二层代表第一个质数的遍历,第三层代表第二个质数的遍历,
然后判断偶数等于两个质数之和的情况,打印即可。
值得一提的是,第一个质数应该小于第二个质数,
遍历到一组和的时候,需要直接结束本轮最外部的偶数循环。
3.代码实现
c
#include <stdio.h>
#include <math.h>
//判断质数的函数
int isPrimer(int n) {
int flag = 1;
//对1和0进行特判
if (n == 1 || n == 0) {
flag = 0;
}
for (int i = 2; i <= sqrt(n); ++i) {
if (n % i == 0) {
//可以被自身整除则不为质数
flag = 0;
}
}
return flag;
}
int main() {
int n;
scanf("%d", &n);
//存放n以内所有的质数
int arr[n];
int cnt = 0;
for (int j = 2; j < n; ++j) {
//存放质数
if (isPrimer(j) == 1) {
arr[cnt] = j;
cnt++;
}
}
//跳出内部循环的标记
int flag = 1;
//遍历偶数
for (int i = 4; i <= n; i += 2) {
for (int j = 0; j < cnt; ++j) {
flag = 1;
for (int k = j; k < cnt; ++k) {
//判断质数之和等于偶数
if (arr[j] + arr[k] == i) {
printf("%d=%d+%d\n", i, arr[j], arr[k]);
flag = 0;
}
}
//当本轮偶数找到质数和之时,跳出本轮
if (flag == 0) {
break;
}
}
}
return 0;
}