欧拉的问题27

时间:2011-04-06 22:05:33

标签: c++

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,为什么会这样呢?我哪里错了?如果仍然不清楚,只要求对特定领域进行更多澄清。

3 个答案:

答案 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可能是个更好的主意,然后才能开始因溢出而出现奇怪的错误。包装