0

我正在尝试解决欧拉问题 18 -> http://projecteuler.net/index.php?section=problems&id=18

我正在尝试用 c++ 来做到这一点(我正在重新学习它,欧拉问题是很好的学习/搜索材料)

#include <iostream>

using namespace std;

long long unsigned countNums(short,short,short array[][15],short,bool,bool);

int main(int argc,char **argv) {

    long long unsigned max = 0;
    long long unsigned sum;


    short piramide[][15] = {{75,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {95,64,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {17,47,82,0,0,0,0,0,0,0,0,0,0,0,0},
                            {18,35,87,10,0,0,0,0,0,0,0,0,0,0,0},
                            {20,4,82,47,65,0,0,0,0,0,0,0,0,0,0},
                            {19,1,23,75,3,34,0,0,0,0,0,0,0,0,0},
                            {88,2,77,73,7,63,67,0,0,0,0,0,0,0,0},
                            {99,65,4 ,28,6,16,70,92,0,0,0,0,0,0,0},
                            {41,41,26,56,83,40,80,70,33,0,0,0,0,0,0},
                            {41,48,72,33,47,32,37,16,94,29,0,0,0,0,0},
                            {53,71,44,65,25,43,91,52,97,51,14,0,0,0,0},
                            {70,11,33,28,77,73,17,78,39,68,17,57,0,0,0},
                            {91,71,52,38,17,14,91,43,58,50,27,29,48,0,0},
                            {63,66,4,68,89,53,67,30,73,16,69,87,40,31,0},
                            {4,62,98,27,23,9,70,98,73,93,38,53,60,4,23}};

    for (short i = 0;i<15;i++) {
        for (short m=0;m<15;m++) {
            if (piramide[i][m] == 0)
                break;
            sum = countNums(i,m,piramide,15,true,true);
            if (sum > max)
                max = sum;
            sum = countNums(i,m,piramide,15,true,false);
            if (sum > max)
                max = sum;
            sum = countNums(i,m,piramide,15,false,true);
            if (sum > max)
                max = sum;
            sum = countNums(i,m,piramide,15,false,false);
            if (sum > max)
               max = sum;

        }

    }
    cout << max;
    return 0;
}


long long unsigned countNums(short start_x,short start_y,short array[][15],short size, bool goright,bool goright2) {
    long long unsigned currentSum;

    currentSum = array[start_x][start_y];

    if (goright) { //go right
        if ((start_x + 1) < size)
            start_x++;
        if ((start_y + 1) < size)
            start_y++;
    }
    else //go down
        if ((start_x + 1) < size)
            start_x++;

    if (goright2) { //still going right
        for (short i = start_x, m = start_y;i< size && m < size;i++,m++) {
            currentSum += array[i][m];         
        }
    }
    else { //still going down
        for (short i = start_x;i<size;i++) {
            currentSum += array[i][start_y];            
        }
    }

    return currentSum;
}

countNums 函数用于向下或对角线。我已经像这样测试了这个功能:

short a = 0;
short b = 0;
cout << countNums(a,b,piramide,15,true,true) << endl;
cout << countNums(a,b,piramide,15,true,false) << endl;
cout << countNums(a,b,piramide,15,false,true) << endl;
cout << countNums(a,b,piramide,15,false,false) << endl;
return 0;

它确实有效(我还稍微改变了函数,所以它会打印它正在经历的每个数字)

但我仍然没有得到正确的结果。这向下和向右并且仍然向右(右侧的相邻数字),向下并继续向下(左侧的相邻数字)。我在这里做错了什么,有人吗?


阿拉斯泰尔:很简单

long long unsigned countNums(short start_x,short start_y,short array[][15],short size, bool goright,bool goright2);

start_x 和 start_y 是数组的坐标 数组是对数组的引用 size 只是数组的大小(它总是 15) goright 是知道我是要往下走还是往下走 goright2 是要知道我要继续往下或往左走

4

4 回答 4

3

好的,首先,我有点不清楚您认为问题出在哪里。我根本无法解析倒数第二句话...

其次,您可能想在这里重新考虑您的设计。考虑执行单个离散任务并且不与应用程序的其余部分交织在一起的功能(即阅读“紧密耦合和松散绑定”)。对我来说,这里的一个大警告是存在一个countNums带有一长串参数的过于通用的函数名称。

我认为如果你把问题分成更小、更容易理解的块,你可能会发现问题更容易找到。我知道我会在这里采用的方法,但我假设练习的全部目的是帮助你练习编程技能,所以我就这样吧……

于 2008-11-17T00:34:05.463 回答
1

我已经解决了这个问题。鉴于 Project Euler 的本质是自己解决问题(“复印已解决的填字游戏并不意味着您解决了它”)并且我不想为其他人毁掉它,我真正能说的是您的解决方案看起来过于复杂。

但是,您可以在阅读文件时解决此问题。以这种方式解决它,问题 #69 将变得轻而易举!

祝你好运!

于 2008-11-17T02:46:16.680 回答
0

我对这个问题有点困惑。
我先清理你的代码。

long long unsigned countNums(short x,
                             short y,
                             short array[][15],
                             short size, 
                             bool goright,
                             bool goright2) 
{
    long long unsigned currentSum;
    currentSum = array[x][y];

    if ((x + 1) < size)    x++; //this happened in both your if cases

    if (goright && ((y + 1) < size)      y++; 

    if (goright2)
    { 
        for (;x< size && y< size;x++,y++)
            currentSum += array[x][y];         

    }
    else 
    {
        for (;x<size;x++) 
            currentSum += array[x][y];            
    }
    return currentSum;
 }

现在我读了这个问题,我不确定它是否在做你想要的。由于这不是您想要的,我建议先对答案进行 psudo-code。忘记代码.. sudo 代码中的答案是什么。
哦,为了所有圣洁的爱。不要在 for 循环中放置一个以上的初始化程序。我知道我会为此受到抨击,但它很混乱而且真的不需要。您可能会考虑的是递归函数。似乎很适合这个问题。

于 2008-11-17T01:24:37.623 回答
0

主函数检查一个条目是否不为零,但它调用的另一个函数不会检查它,即使它再次更改索引。我不知道,我真的不明白你想做什么。

我看到 15 个元素的数组大小为 15,声明的索引是否也从 0 开始?让我检查一下。只要确保,用大小声明,但基于 0 访问。很好。

为什么你在一个地方使用了嵌套的 for 语句,但后来却使用了复合条件 for 语句?最好检查&&没有比 更高的优先级<第 8 组在这里击败第 13 组。增量运算符不在语句中多次使用,这很好。

听起来你以前用另一种语言做过这个问题,你能不能也跟踪一下,找到你的新程序首先不同的地方?

其他人是对的,这个问题令人困惑。我会首先尝试解决问题,如果金字塔从那个点开始并从底部到顶部构建它,那么在另一个矩阵中建立子分数给出最高分数。

于 2008-11-17T01:45:47.300 回答