在项目euler#8上得到错误的答案

时间:2016-03-25 10:01:21

标签: c++

这可能会重复,但请相信我,我找到了满意的答案。 有人可以告诉我为什么我对这个问题的答案是错误的:https://projecteuler.net/problem=8。我用暴力强迫。我的代码给出了小数的正确答案。然而,对于13位数,它给出了错误的答案。代码:

#include <iostream>
#include<string>
#include<cmath>
using namespace std;

int main()
{
     string str = "73167176531330624919225119674426574742355349194934969835203127745063262395783180169848018694788518438586156078911294949545950173795833195285320880551112540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
    int len = str.size();
    double maxi = 0, product = 1;
    for(int i = 0; i < len - 13; i ++){
        product = (str[i] - '0') * (str[i+1] - '0') * (str[i+2] - '0') * (str[i+3] - '0') * (str[i+4] - '0') * (str[i+5] - '0')* (str[i+6] - '0') * (str[i+7] - '0') * (str[i+8] - '0') * (str[i+9] - '0') * (str[i+10] - '0') * (str[i+11] - '0') * (str[i+12] - '0');
        if(maxi < product){
            maxi = product;
        }
    }
    cout << maxi;
    cin.get();
    return 0;
}

他们给出的例子。这是4连续数字的乘积,我得到正确答案5832.代码相同:

#include <iostream>
#include<string>
#include<cmath>
using namespace std;

int main()
{
     string str = "73167176531330624919225119674426574742355349194934969835203127745063262395783180169848018694788518438586156078911294949545950173795833195285320880551112540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
    int len = str.size();
    double maxi = 0, product = 1;
    for(int i = 0; i < len - 13; i ++){
        product = (str[i] - '0') * (str[i+1] - '0') * (str[i+2] - '0') * (str[i+3] - '0'); //* (str[i+4] - '0') * (str[i+5] - '0')* (str[i+6] - '0') * (str[i+7] - '0') * (str[i+8] - '0') * (str[i+9] - '0') * (str[i+10] - '0') * (str[i+11] - '0') * (str[i+12] - '0');
        if(maxi < product){
            maxi = product;
        }
    }
    cout << maxi;
    cin.get();
    return 0;
}

2 个答案:

答案 0 :(得分:2)

最可能的原因是发生了整数溢出 13位数的乘积的最大值为9^13,而double无法准确支持。

因此,解决方案是使用long long代替double

答案 1 :(得分:0)

每次遇到这样的问题时,如果您获得了一个示例的正确结果,但是对于大型数据集,您应该考虑溢出。您的productmaxi类型为double。我将它们更改为long long并获得了正确的结果。我还清理了一下你的代码。在这里

#include <iostream>
#include<string>
#include<cmath>
using namespace std;

int main()
{
    string str = "73167176531330624919225119674426574742355349194934" \
                 "96983520312774506326239578318016984801869478851843" \
                 "85861560789112949495459501737958331952853208805511" \
                 "12540698747158523863050715693290963295227443043557" \
                 "66896648950445244523161731856403098711121722383113" \
                 "62229893423380308135336276614282806444486645238749" \
                 "30358907296290491560440772390713810515859307960866" \
                 "70172427121883998797908792274921901699720888093776" \
                 "65727333001053367881220235421809751254540594752243" \
                 "52584907711670556013604839586446706324415722155397" \
                 "53697817977846174064955149290862569321978468622482" \
                 "83972241375657056057490261407972968652414535100474" \
                 "82166370484403199890008895243450658541227588666881" \
                 "16427171479924442928230863465674813919123162824586" \
                 "17866458359124566529476545682848912883142607690042" \
                 "24219022671055626321111109370544217506941658960408" \
                 "07198403850962455444362981230987879927244284909188" \
                 "84580156166097919133875499200524063689912560717606" \
                 "05886116467109405077541002256983155200055935729725" \
                 "71636269561882670428252483600823257530420752963450";

    const size_t adjacent = 13;
    size_t len = str.size();

    long long max = 0, product = 1;
    for(size_t i = 0; i+adjacent < len; ++i) {
        product = 1;
        for (size_t j = 0; j < adjacent; ++j)
            product *= str[i+j] - '0';
        if (max < product)
            max = product;
    }
    cout << max << endl;
    return 0;
}

Demo