Euler published the remarkable quadratic formula: n² + n + 41 It turns out that the formula will produce 40 primes for the consecutive
值n = 0到39.但是,当n =时 40,40 ^(2)+ 40 + 41 = 40(40 + 1)+ 41 被41整除,当然可以 n = 41,41 2 + 41 + 41很明显 被41整除。
Using computers, the incredible formula n² − 79n + 1601 was
发现,它产生80个素数 对于连续值n = 0到 79.系数-79和1601的乘积是-126479。
Considering quadratics of the form: n² + an + b, where |a| < 1000 and |b| < 1000 where |n| is the modulus/absolute value of n e.g. |11| = 11 and |−4| = 4 Find the product of the coefficients, a and b, for the
产生的二次表达式 最大素数 n的连续值,以。开头 n = 0。
这是Euler 27的问题。
我尝试了一个解决方案,试图找到方程式n ^ 2 + n + 41,看看我的逻辑是否正确,然后我将尝试查看它是否适用于实际问题。这是我的代码(我将发表评论解释整个程序,我将首先从int main函数开始阅读)只需确保阅读注释,以便您可以理解我的逻辑:
#include <iostream>
using namespace std;
bool isPrime(int c) {
int test;
//Eliminate with some simple primes to start off with to increase speed...
if (c == 2) {
return true;
}
if (c == 3) {
return true;
}
if (c == 5) {
return true;
}
//Actual elimination starts here.
if (c <= 1 || c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
return false;
}
//Then using brute force test if c is divisible by anything lower than it except 1
//only if it gets past the first round of elimination, and if it doesn't
//pass this round return false.
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
//If the c pasts all these tests it should be prime, therefore return true.
return true;
}
int main (int argc, char * const argv[]) {
//a as in n^2 + "a"n + b
int a = 0;
//b as in n^2 + an + "b"
int b = 0;
//n as in "n"^2 + a"n" + b
int n = 0;
//this will hold the result of n^2 + an + b so if n = 1 a = 1
//and b = 1 then c = 1^2 + 1(1) + 1 = 3
int c = 0;
//bestChain: This is to keep track for the longest chain of primes
//in a row found.
int bestChain = 0;
//chain: the current amount of primes in a row.
int chain = 0;
//bestAB: Will hold the value for the two numbers a and b that
// give the most consecutive primes.
int bestAB[2] = { 0 };
//Check every value of a in this loop
for (a = 0; a < 40; a++) {
//Check every value of b in this loop.
for (b = 0; b < 42; b++) {
//Give c a starting value
c = n*n + a*n + b;
//(1)Check if it is prime. And keep checking until it is not
//and keep incrementing n and the chain. (2)If it not prime then che
//ck if chain is the highest chain and assign the bestChain
// to the current chain. (3)Either way reset the values
// of n and chain.
//(1)
while (isPrime(c) == true) {
n++;
c = n*n + a*n + b;
chain++;
}
//(2)
if (bestChain < chain) {
bestChain = chain;
bestAB[0] = a;
bestAB[1] = b;
chain = 0;
n = 0;
}
//(3)
else {
n = 0;
chain = 0;
}
}
}
//Lastly print out the best values of a and b.
cout << bestAB[0] << " " << bestAB[1];
return 0;
}
但是,我分别得到a和b的结果0和2,为什么会这样呢?我哪里错了?如果仍然不清楚,只要求对特定领域进行更多澄清。
答案 0 :(得分:5)
你的isprime方法效率低下 - 但也错了:
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
在for循环的第一次迭代中,test
= c
,所以c % test
只是c % c
,它总是为0.所以你的isprime方法声称一切是非素数(2,3,5除外)
答案 1 :(得分:2)
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
你看到了问题吗?如果没有,请尝试手工制作一些小样本值。
答案 2 :(得分:1)
正如其他人所指出的,您的问题出在isPrime方法(test = c
,因此test % c = c % c == 0
始终为真)。
通过将isPrime
初始化为sqrt(c)(并且仅检查奇数),可以使test
函数在O(sqrt(n))而不是O(n)中运行。很容易看出,如果数字A可以被B&lt; sqrt(A),则C = A / B必须> SQRT(A)。因此,如果没有除数&lt; sqrt(A),将没有除数&gt; SQRT(A)。
当然,通过使用概率素性测试,例如,你甚至可以更快地运行它。 Miller-Rabin's primality test
另外,我不确定,但我怀疑你可能会很快达到int
的限制。从一开始就使用unsigned long long
可能是个更好的主意,然后才能开始因溢出而出现奇怪的错误。包装