Problem with Euler 27

Problem with Euler 27

本文关键字:Euler with Problem      更新时间:2023-10-16
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²+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主函数开始阅读(只需确保阅读注释,这样你就可以理解我的逻辑:

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

您的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(

for (test = c; test > 1; test--) {
    if (c % test == 0) {
        return false;
    }
}

你觉得有什么问题吗?如果没有,请尝试手工计算一些小样本值。

正如其他人所指出的,您的问题在isPrime方法中(test = c,所以test % c = c % c == 0总是真的(。

通过将test初始化为sqrt(c((并且只检查奇数(,可以使isPrime函数在O(sqrt(n((而不是O(n(中运行。很容易看出,如果一个数a可以被B<则C=A/B必须大于sqrt(A(。因此,如果没有除数<sqrt(A(,则不会有大于sqrt(A(的除数。

当然,你甚至可以通过使用概率素性测试,比如Miller Rabin的素性测试来更快地运行它。

此外,我不确定,但我怀疑你可能很快达到int的极限。从一开始就使用unsigned long long可能是一个更好的主意,在您开始因溢出而出现奇怪的错误之前;包装。