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 は配列の座標です array は配列への参照です size はちょうど配列のサイズです (常に 15 です)私は下に行くか、左に行きます

4

4 に答える 4

3

わかりましたので、まず最初に、問題が何であると考えているかについて、私は少し不明確です。その最後から 2 番目の文をまったく解析できません...

次に、ここで設計を再考することをお勧めします。単一の個別のタスクを実行し、アプリケーションの残りの部分と絡み合っていない関数について考えてください (つまり、「密結合と疎結合」を読んでください)。私にとって大きな警告ベルは、countNums引数の長いリストを持つ過度に一般的な関数名の存在です。

問題をより小さく、より理解しやすいチャンクに分割すると、問題を見つけやすくなる可能性があると思います。私がここでとるアプローチは知っていますが、演習の全体的なポイントは、プログラミング スキルの練習を支援することであると想定しているため、そのままにしておきます...

于 2008-11-17T00:34:05.463 に答える
1

私はこの問題を解決しました。プロジェクトオイラーの性質を考えると、自分で問題を解決することであり(「解決したクロスワードパズルをコピーすることは、それを解決したことを意味するわけではありません」)、他の誰かのためにこれを台無しにしたくないので、私が本当に言えるのはソリューションが非常に複雑に見えること。

ただし、ファイルを読んでいるときにこの問題を解決することはできます。このように解決すれば、問題#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;
 }

今、私は質問を読みましたが、あなたが望むことをしているのかわかりません。これはあなたが望むものではないので、最初に答えを疑似コード化することをお勧めします。コードを忘れてください.sudoコードの答えは何ですか。
ああ、そして聖なるすべてのものへの愛のために。for ループに複数のイニシャライザを置かないでください。私はそのために高射砲を得るつもりだと知っていますが、それは面倒で本当に必要ありません. あなたが考えるかもしれないのは再帰関数です。この問題には理想的です。

于 2008-11-17T01:24:37.623 に答える
0

メイン関数はエントリがゼロでないことを確認しますが、メイン関数が呼び出す他の関数はインデックスを再度変更してもそれを確認しません。わかりません、あなたが何をしようとしているのかよくわかりません。

15 個の要素に対して配列サイズ 15 が表示されますが、宣言のインデックスも 0 から始まりますか? 少し確認させてください。念のため、サイズで宣言しているが、0 を基準にアクセスしている。

ネストされた for ステートメントを 1 か所で使用したのに、後で for ステートメントの複合条件を使用したのはなぜですか? &&の優先順位が よりも高くないことを確認してください<。ここでは、グループ 8 がグループ 13 を打ち負かしています。インクリメント演算子がステートメントで複数回使用されていないことは良いことです。

以前に別の言語でこの問題を解決したことがあるようですが、それについても追跡して、新しいプログラムが最初に異なる場所を見つけていただけますか?

他の人は正しいです、質問は紛らわしいです。私は最初に、別のマトリックスでサブスコアを構築して問題を解決しようとし、ピラミッドがその時点で開始された場合に最高のスコアを与え、一番下の行から一番上までそれを構築します。

于 2008-11-17T01:45:47.300 に答える