/* 题目描述: 哥德巴赫猜想:任意一个大于等于4的偶数都能表示为两个质数之和 输入: 有多组测试数据,每行一个小于1e7的并且大于2的偶数 以EOF标志结束程序。 输出: 对于每组测试,输出拆分的结果,有多组结果则都要输出 输出顺序按拆分的第一个数的大小从小到大输出 样例输入: 6 14 22 样例输出: 6=3+3 14=3+11 14=7+7 22=3+19 22=5+17 22=11+11 难度:Very Easy */ // 此题为典型的空间换时间 #include <cstdio> #include <cmath> const int NUM_TOTAL = 10000000; // 1e7 const int PRIME_TOTAL = 664579; // 1e7以内的质数总数 bool primeNumFlag[NUM_TOTAL] = {false, false, true, true}; // 标记各下标对应的数字是否为质数 int primeNum[PRIME_TOTAL] = {2, 3}; // 用来记录给定范围内的所有质数, 初始化为第一个偶质数和第一个奇质数 int primeCount = 2; // 当前已记录质数总数 // 利用记录质数的数组判断一个数是否为质数 bool isPrime(int num) { int squareRoot = (int) sqrt(num); // 测试此数是否能被比它小的质数所整除, 如果可以说明它不是质数 // 只求到平方根为提高效率的一贯做法 // 只测试能否被质数整除, 因为能被合数整除肯定能被其质数因子所整除 for( int i = 0; primeNum[i] <= squareRoot; i++ ) if( num % primeNum[i] == 0 ) return false; // 如果都不能整除, 说明此数为质数 return true; } int main() { int n = 0; // 用户输入 int f2 = 0; // 加数 while( scanf(“%d”, &n) != EOF ) { // 先统计所有比这个数小的质数 // 多次输入将复用前面的统计结果提高效率, 只统计未被统计的质数 // 只判断奇数提高效率, 因为偶质数只有2, 已在前面初始化 for( int i = primeNum[primeCount – 1] + 2; i < n; i += 2 ) { if( isPrime(i) ) // 如果是质数 { primeNumFlag[i] = true; // 标记 primeNum[primeCount] = i; // 记录 primeCount++; // 统计 } } // 利用统计的结果进行计算 // 只需计算一半的数, 避免重复 for( int i = 0; primeNum[i] <= n / 2; i++ ) { f2 = n – primeNum[i]; if( primeNumFlag[f2] ) printf(“%d=%d+%d/n”, n, primeNum[i], f2); } } return 0; }