题目背景
1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和。质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是质数,因为6除了约数1和6之外还有约数2和3。需要特别说明的是1不是质数。
这就是哥德巴赫猜想。欧拉在回信中说,他相信这个猜想是正确的,但他不能证明。
从此,这道数学难题引起了几乎所有数学家的注意。哥德巴赫猜想由此成为数学皇冠上一颗可望不可及的“明珠”。
题目描述
现在请你编一个程序验证哥德巴赫猜想。
先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数。
输入格式
仅有一行,包含一个正奇数n,其中9<n<20000
输出格式
仅有一行,输出3个质数,这3个质数之和等于输入的奇数。 相邻两个质数之间用一个空格隔开,最后一个质数后面没有空格。
如果表示方法不唯一,请输出第一个质数最小的方案。 如果第一个质数最小的方案不唯一,请输出第一个质数最小的同时,第二个质数最小的方案。
是比较低效的暴力算法,因为n<20000,所以一般通过部分优化,暴搜还是可以AC的。(没优化前,10个案例过了9个,最后一个案例耗时1.02秒,超出0.02秒,一般1s计算机可以计算10的7次方,不是特别刁难的例子的话,都可以试试暴力算法,但是这样不利于程序员的成长)
#include<iostream>
#include<cmath>
using namespace std;
bool is_primer(int n) {
if (n == 2) {
return true;
}
if (n == 1 || n % 2==0) {
return false;
}
int s_sqrt = sqrt(double(n));
for (int i = 3; i <= s_sqrt; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
int main() {
int n;
cin >> n;
int i, j, k;
for (i = 2; i < n; i++) {
for (j = 2; j < n; j++) {
for (k = 2; k < n; k++) {
if (i + j + k == n) {
if (is_primer(i) && is_primer(j) && is_primer(k)) {
cout << i << " " << j << " " << k;
return 0;
}
}
if (i + j + k < n - 2000) {
//跳过优化
k += 2000;
}
}
if (i + j + k < n - 1000) {
//跳过优化
j += 1000;
}
}
}
return 0;
}
其实除了暴力算法,还是可以通过暴力打表的方法的。先使用freopen把0~20000以内的素数都计算出来,然后把这个数据放在一个数组里,缺点是代码长度比较长,如果超过2^3 KB就不能用打表法(注:下面的代码长度12.34KB,已经算比较长了),好处是耗时很短,最长的案例只耗时16ms.
#include<iostream>
#include<cmath>
using namespace std;
int main() {
int s[] = {
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619,1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357,2371,2377,2381,2383,2389,2393,2399,2411,2417,2423,2437,2441,2447,2459

该博客介绍了哥德巴赫猜想的历史背景及其成为未解数学难题的地位。提出了编写程序验证猜想的要求,即给定一个奇数n,找到三个质数使它们的和等于n。讨论了暴力算法在限制范围内可以解决问题,但效率低下,以及通过预计算素数列表(打表法)来提高效率的方法,尽管会增加代码长度。博主鼓励分享更多高效算法进行交流。
最低0.47元/天 解锁文章
675

被折叠的 条评论
为什么被折叠?



