トップページに戻る    次のC++のサンプルへ    前のC++のサンプルへ

Problem28 対角線上の数字の合計

問題

1から初めて右方向に進み時計回りに数字を増やしていき,
5×5の螺旋が以下のように生成される:

21 22 23 24 25
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

両対角線上の数字の合計は101であることが確かめられる.

1001×1001の螺旋を同じ方法で生成したとき, 対角線上の数字の合計はいくつだろうか?


ソース

#include <stdio.h>

class CManageArr{
public:
    //static const int Haba = 5;
    static const int Haba = 1001;
    static const int UB = Haba-1;
private:
    int Ban[Haba][Haba];
public:
    void SetVal(int pX,int pY,int pVal ){Ban[pX][pY] = pVal;}
    int GetVal(int pX,int pY){return Ban[pX][pY];}
}ManageArr;

void main()
{
    int X, Y;
    X = Y = ManageArr.UB / 2;

    int MoveX, MoveY;
    MoveX = MoveY = 1;
    int NextMove = 2;

    int WillSetVal = 1;
    ManageArr.SetVal(X,Y,WillSetVal);

    while (true) {
        if (MoveX > 0) {
            if (++X > ManageArr.UB) break;
            --MoveX;
            ManageArr.SetVal(X,Y,++WillSetVal);
            continue;
        }
        else if (MoveX < 0) {
            if (--X < 0) break;
            ++MoveX;
            ManageArr.SetVal(X,Y,++WillSetVal);
            continue;
        }
        else if (MoveY > 0) {
            if (++Y > ManageArr.UB) break;
            --MoveY;
            ManageArr.SetVal(X,Y,++WillSetVal);
            continue;
        }
        else if (MoveY < 0) {
            if (--Y < 0) break;
            ++MoveY;
            ManageArr.SetVal(X,Y,++WillSetVal);
            continue;
        }
        if (NextMove % 2 == 0) {
            MoveX = MoveY = -NextMove++;
        }
        else {
            MoveX = MoveY = NextMove++;
        }
    }

    if (CManageArr::Haba == 5){
        for (int I = 0; I <= ManageArr.UB; I++) {
            for (int J = 0; J <= ManageArr.UB; J++) {
                printf("%8d,",ManageArr.GetVal(J,I));
            }
            printf("\n");
        }
    }

    __int64 SumVal = 0;
    for (int I = 0; I <= ManageArr.UB; I++) {
        SumVal += ManageArr.GetVal(I, I);
        if (I != ManageArr.UB / 2)
            SumVal += ManageArr.GetVal(ManageArr.UB - I, I);
    }
    printf("合計=%I64d\n",SumVal);
}


実行結果

合計=669171001


解説

ビルトインのint型配列の配列で、2次元配列を扱うクラスを用意してます。