C ++中的Euler 8项目,我不知道怎么了

时间:2020-08-19 22:06:04

标签: c++ algorithm

问题from here:在nbAdjacent中找到具有最高乘积的nStr位数字。因此,我将数字存储为字符串,并且我的代码打印出的所有内容都是正确的,但最终结果是错误的,我无法弄清楚原因...在此期间,我继续了Euler项目,但这给我带来了麻烦。 这是我的代码:

std::string nStr = "731...50";  // a 1000-digit number
uint64_t prod = 1;
int nbAdjacent = 13;
int max = 0;
for (int i = 0; i <=988; i++)
{
    for (int j = 0; j < nbAdjacent; j++)
    {
        // yes i thought about that ;)
        prod *= nStr[i + j] - '0';
    }
    if (prod > max)
    {
        max = prod;
        for (int j = 0; j < nbAdjacent-1; j++)
            std::cout << nStr[i + j] << " * ";
        // each new max is printed
        std::cout << nStr[i + nbAdjacent - 1] << " = " << prod << std::endl;
    }
    prod = 1;
}

并打印以下内容:

7 * 3 * 1 * 6 * 7 * 1 * 7 * 6 * 5 * 3 * 1 * 3 * 3 = 5000940
4 * 9 * 1 * 9 * 2 * 2 * 5 * 1 * 1 * 9 * 6 * 7 * 4 = 9797760
9 * 2 * 2 * 5 * 1 * 1 * 9 * 6 * 7 * 4 * 4 * 2 * 6 = 13063680
2 * 5 * 1 * 1 * 9 * 6 * 7 * 4 * 4 * 2 * 6 * 5 * 7 = 25401600
5 * 1 * 1 * 9 * 6 * 7 * 4 * 4 * 2 * 6 * 5 * 7 * 4 = 50803200
1 * 1 * 9 * 6 * 7 * 4 * 4 * 2 * 6 * 5 * 7 * 4 * 7 = 71124480
1 * 9 * 6 * 7 * 4 * 4 * 2 * 6 * 5 * 7 * 4 * 7 * 4 = 284497920
9 * 6 * 7 * 4 * 4 * 2 * 6 * 5 * 7 * 4 * 7 * 4 * 2 = 568995840
5 * 3 * 4 * 9 * 1 * 9 * 4 * 9 * 3 * 4 * 9 * 6 * 9 = 1020366720
3 * 4 * 9 * 1 * 9 * 4 * 9 * 3 * 4 * 9 * 6 * 9 * 8 = 1632586752
9 * 1 * 9 * 4 * 9 * 3 * 4 * 9 * 6 * 9 * 8 * 3 * 5 = 2040733440
8 * 6 * 9 * 4 * 7 * 8 * 8 * 5 * 1 * 8 * 4 * 3 * 8 = 2972712960

我在for循环中检查了索引错误,但没有发现错误...

1 个答案:

答案 0 :(得分:0)

解决方案中的一个问题是您要循环访问988,这是不正确的,因为您将访问nStr[i + j] = nStr[988+12]=nStr[1000],它越界并且包含垃圾。 正如其他人指出的那样,您可以获得的最大解决方案是9^13,它至少需要42位(log2(9^13)=41.2),因此请使用long long int之类的东西,以确保在所有体系结构上都具有64位。 提示,请尝试避免在程序中对诸如988之类的值进行硬编码,而要对其进行计算。

对于该代码,可能的改进是使用滑动窗口而不是每次都计算乘积,并跟踪当前乘以的13位数字。然后,您将每个循环迭代除以最后一位并乘以新的一位。这样可以加快解决方案的速度,该解决方案将是O(n)而不是O(s*n)。由于某些数字可能为零,因此我们可以在窗口中保留一个计数器,以了解多少个数字为0,如果该计数器为> 0,我们将知道乘积为0。

这里有一个使用c ++的示例解决方案,可以输出正确的结果。

#include <iostream>
#include <string>

using namespace std;

const string digits = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
const int nAdj = 13;

int main()
{
    int n = digits.size();
    long long int prod = 1;
    long long int max = 0;
    int zeros = 0;

    // precompute sliding window
    for (int i = 0; i < nAdj-1; ++i)
    {
        int d = digits[i]-'0';
        if(d==0) ++zeros;
        else prod *= d;
    }

    for (int i = nAdj-1; i < n; ++i)
    {
        // add new digit
        int d = digits[i]-'0';
        if(d==0) ++zeros;
        else prod *= d;

        //check best
        if(zeros == 0)
        {
            if(prod > max) max = prod;
        }

        //remove last digit
        d = digits[i-nAdj+1]-'0';
        if(d==0) --zeros;
        else prod /= d;
    }

    cout << "The max is: " << max << endl; // 23514624000
    return 0;
}
相关问题