项目欧拉11 c ++错误答案

时间:2015-06-08 09:58:14

标签: c++ grid

20×20网格中相同方向(上,下,左,右或对角)的四个相邻数字的最大乘积是什么?

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

我的c ++代码:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream fd ("file.txt"); // this file contains the grid
    int A[463],max=-1;

    for (int i=1;i<=400;i++){
        fd >> A[i];
    }
    for (int i=463;i>400;i--){ // zero out array numbers that exceed 400
        A[i]=0;
    }
    for (int i=1;i<=400;i++){
        if ((A[i]*A[i+20]*A[i+40]*A[i+60])>max){ //vertical maximum
            max=A[i]*A[i+20]*A[i+40]*A[i+60];

         }
         if ((i%20!=0)||((i-18)%20!=0)||((i-19)%20!=0)){  //diagnol \ maximum (first if checks if out of bounds)
            if ((A[i]*A[i+21]*A[i+42]*A[i+63])>max){
                max=A[i]*A[i+21]*A[i+42]*A[i+63];
            }
        }
        if (((i-1)%20!=0)||((i-2)%20!=0)||((i-3)%20!=0)){// diagnol / maximum (first if checks if out of bounds)
            if ((A[i]*A[i+19]*A[i+18]*A[i+17])>max){
                max=A[i]*A[i+19]*A[i+18]*A[i+17];
            }
        }
        if ((i+2)%20!=0){ // horizontal maximum (first if checks if out of bounds)
            if ((A[i]*A[i+1]*A[i+2]*A[i+3])>max){
                max=A[i]*A[i+1]*A[i+2]*A[i+3];
            }
        }
    }
     cout <<max;
     fd.close();
    return 0;
}

使用此代码,我得到答案51267216,这是垂直答案,但这个答案不正确,我认为我的诊断检查有问题。 如果我输出诊断最大值,我会得到一些接近最大垂直但不正确的4xxxxxxx。 P.S我检查/和\ diagnols。

2 个答案:

答案 0 :(得分:0)

事实上,对角线的测试看起来是错误的。 例如,\对角线测试应该是:

// not starting from the 3 rightmost columns,
// not starting from the 3 bottom rows
if ((i%20 <= 16) && i < 20*17) 

另一个对角线应为:

// idem above:
if ((i%20 >= 3) && i < 20*17)

修改:

右上角到左下角的索引是错误的:它们应该是{0,19,2 * 19,3 * 19},即{0,19,38,57}:

这是整个for循环,输出正确的结果:(70600674)

for (int i=0; i < 400; ++i) // <- I used a regular array indexed from 0
{
    if (i < 17 * 20)
    {
        if ((A[i] * A[i + 20] * A[i + 40] * A[i + 60]) > max)
        {
            max = A[i] * A[i + 20] * A[i + 40] * A[i + 60];
        }
        if (i % 20 <= 16)
        {
            if ((A[i] * A[i + 21] * A[i + 42] * A[i + 63]) > max)
            {
                max = A[i] * A[i + 21] * A[i + 42] * A[i + 63];
            }
        }
        if (i % 20 >= 3)
        {
            if ((A[i] * A[i + 19] * A[i + 38] * A[i + 57]) > max)
            {
                max = A[i] * A[i + 19] * A[i + 38] * A[i + 57];
            }
        }
    }
    if (i % 20 <= 16)
    {
        if ((A[i]*A[i+1]*A[i+2]*A[i+3])>max)
        {
            max=A[i]*A[i+1]*A[i+2]*A[i+3];
        }
    }
}

在旁注中,二维数组会更清晰(你可能不会犯这样的错误)

答案 1 :(得分:0)

您应该做的第一件事是使用2D阵列。它们使您的问题看起来更容易。第二件事 - 使用常量。不要使用无意义的数字,这些数字看起来像黑魔法的第二个人。第三件事 - 使用三行三列的右,左,下填充。最后要记住的事情 - 像其他人一样阅读你的代码。即使只有你和一台电脑会看到代码 - 这是一个好习惯,并在你申请工作时给你一个进步。

const int parameters = 20;
const int padding = 3;
int tab[parameters + padding][parameters + padding];

请参阅?它更容易阅读并告诉你你在做什么。额外的列和行将为我们提供大量if if语句。您可以将程序打包到函数中 - 它更易于阅读和使用。通常我会通过定义一个新类来实现,但出于算法目的,我将使用全局变量和函数。

#include <fstream>

using namespace std;

const int parameters = 20;
const int padding = 3;
int tab[parameters + padding][parameters + 2*padding];

int diagonalLeft(int i, int j) {
    int answer = 1;
    for (int u = 0; u <= padding; u++)
        answer *= tab[i - u][j - u];
    return answer;
}

int diagonalRight(int i, int j) {
    int answer = 1;
    for (int u = 0; u <= padding; u++)
        answer *= tab[i - u][j + u];
    return answer;
}

int vertical(int i, int j) {
    int answer = 1;
    for (int u = 0; u <= padding; u++)
        answer *= tab[i + u][j];
    return answer;
}

int horizontal(int i, int j){
    int answer = 1;
    for (int u = 0; u <= padding; u++)
        answer *= tab[i][j + u];
    return answer;
}

int max(int a, int b) {
    if (a > b)
        return a;
    return b;
}

int main() {
    ifstream input("file.txt");
    for (int i = 0; i < parameters; i++)
        for (int j = padding; j < parameters + padding; j++)
            input >> tab[i][j];
    int maximum = 0;
    int temp;
    for (int i = 0; i < parameters; i++) {
        for (int j = padding; j < parameters + padding; j++) {
            temp = diagonalLeft(i, j);
            temp = max(temp, diagonalRight(i, j));
            temp = max(temp, vertical(i, j));
            temp = max(temp, horizontal(i, j));
            maximum = max(maximum, temp);
        }
    }
    cout << maximum << endl;
    input.close();
    return 0;
}

如果您的代码不仅更容易阅读,更容易在干净的代码中找到错误。甚至不要试图在你的代码中找到它们,因为它甚至需要几个小时。

发明二维阵列是有原因的。由于这个一维数组,你可能会有比你想象的更多的错误。

查看if语句的大小。我的更短,更容易调试。桌子周围的填充物让我没有例外,就像你拥有的那样。