0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【配列 2】立体で計算

Posted at

今回は paiza の「【配列 2】立体で計算」の問題に挑戦!

三次元配列の扱いに初挑戦!


問題概要

〇 入力

  • N × N × N の立方体配列が与えられる
    入力形式は 平面ごとに1行ずつの N×N 行列が N 層分並んだ形式

  • 例えば N = 2 の場合:

1 2   ← 1層目
2 3
3 2   ← 2層目
2 1

〇 出力

  • N 要素からなる縦列・横列・斜め列の和の最大値を出力
  • 「縦列・横列・斜め列」の意味:
    • 縦列(x方向、y方向、z方向いずれも含む)
      • 例:同じ層の横一列、縦一列、層をまたぐ列
    • 斜め列
      • 平面内の斜め
        • XY平面の左上→右下、右上→左下
        • YZ平面や ZX平面も同様
      • 立体の空間対角線
        • 立方体の一番手前の角から一番奥の角までの対角線

〇 条件・制約

  • 各列の長さは N
  • 立方体の全ての行・列・平面斜め・空間対角線を考慮する
  • N の最大値が50なので、単純な三重ループでも十分計算可能



入力例:

2  // N
1 2
2 3
3 2
2 1

出力例:

6






✅ OK例:

const fs = require("fs");
// 入力をスペース区切りでまとめて数値配列に変換
const input = fs.readFileSync(0, "utf8").trim().split(/\s+/).map(Number);

let idx = 0;
const N = input[idx++]; // 立方体の一辺の長さ

// cube[z][y][x] として 3次元配列を初期化
const cube = Array.from({ length: N }, () =>
  Array.from({ length: N }, () => Array(N).fill(0))
);

// --- 入力値を cube[z][y][x] に格納 ---
for (let z = 0; z < N; z++) {
  for (let y = 0; y < N; y++) {
    for (let x = 0; x < N; x++) {
      cube[z][y][x] = input[idx++]; // 1つずつ取り出して代入
    }
  }
}

let maxSum = -Infinity; // 最大値の初期化


// -----------------------------
// 1. 各行 (x方向) の合計
// -----------------------------

for (let z = 0; z < N; z++) {
  for (let y = 0; y < N; y++) {
    let sum = 0;
    for (let x = 0; x < N; x++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}


// -----------------------------
// 2. 各列 (y方向) の合計
// -----------------------------

for (let z = 0; z < N; z++) {
  for (let x = 0; x < N; x++) {
    let sum = 0;
    for (let y = 0; y < N; y++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}


// -----------------------------
// 3. 縦方向 (z方向) の合計
// -----------------------------

for (let y = 0; y < N; y++) {
  for (let x = 0; x < N; x++) {
    let sum = 0;
    for (let z = 0; z < N; z++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}


// -----------------------------
// 4. 各平面の対角線
// -----------------------------

// (a) XY平面ごとに対角線
for (let z = 0; z < N; z++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[z][i][i];           // 左上→右下
    d2 += cube[z][i][N - 1 - i];   // 右上→左下
  }
  maxSum = Math.max(maxSum, d1, d2);
}

// (b) YZ平面ごとに対角線
for (let x = 0; x < N; x++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[i][i][x];           // 前上→後下
    d2 += cube[N - 1 - i][i][x];   // 前下→後上
  }
  maxSum = Math.max(maxSum, d1, d2);
}

// (c) ZX平面ごとに対角線
for (let y = 0; y < N; y++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[i][y][i];           // 左奥→右手前
    d2 += cube[N - 1 - i][y][i];   // 右奥→左手前
  }
  maxSum = Math.max(maxSum, d1, d2);
}


// -----------------------------
// 5. 立体の空間対角線 (大対角線)
// -----------------------------

let diag1 = 0, diag2 = 0, diag3 = 0, diag4 = 0;
for (let i = 0; i < N; i++) {
  diag1 += cube[i][i][i];                   // (0,0,0) → (N-1,N-1,N-1)
  diag2 += cube[i][i][N - 1 - i];           // (0,0,N-1) → (N-1,N-1,0)
  diag3 += cube[i][N - 1 - i][i];           // (0,N-1,0) → (N-1,0,N-1)
  diag4 += cube[i][N - 1 - i][N - 1 - i];   // (0,N-1,N-1) → (N-1,0,0)
}
maxSum = Math.max(maxSum, diag1, diag2, diag3, diag4);


// -----------------------------
// 出力
// -----------------------------

console.log(maxSum);

1️⃣ 入力の取得と立方体の初期化

const fs = require("fs");
const input = fs.readFileSync(0, "utf8").trim().split(/\s+/).map(Number);

let idx = 0;
const N = input[idx++]; // 立方体の一辺の長さ

// cube[z][y][x] として 3次元配列を初期化
const cube = Array.from({ length: N }, () =>
  Array.from({ length: N }, () => Array(N).fill(0))
);

ポイント

  • N は立方体の1辺の長さ。例えば N=2 なら 2×2×2 の立方体。
  • cube[z][y][x] という 3次元配列 を使って立方体を表現。
    • z軸:前→後
    • y軸:上→下
    • x軸:左→右
  • このとき cube[0][0][0] が立方体の「左上前端」、cube[N-1][N-1][N-1] が「右下後端」に対応。


2️⃣ 入力値を立方体に格納

for (let z = 0; z < N; z++) {
  for (let y = 0; y < N; y++) {
    for (let x = 0; x < N; x++) {
      cube[z][y][x] = input[idx++]; // 1つずつ取り出して代入
    }
  }
}

ポイント

  • 入力は1行ずつ N×N の平面が並んでいるイメージ。
  • 外側のループ z が前→後の層を移動。
  • 真ん中のループ y が上から下の行を移動。
  • 内側のループ x が行内の左から右の要素を取り出す。
  • 結果として cube[z][y][x] に立方体の全データが格納される。


3️⃣ 最大値を求めるための変数初期化

let maxSum = -Infinity; // 最大値の初期化

すべての「縦・横・斜めの列の合計」を調べ、最終的にここに最大値を格納する。



4️⃣ 各行 (x方向) の合計

for (let z = 0; z < N; z++) {
  for (let y = 0; y < N; y++) {
    let sum = 0;
    for (let x = 0; x < N; x++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}

ポイント

  • XY平面の「横一列」の合計を計算
  • イメージ:
[x][y] ← 水平方向の行
z = 前→後の層ごとに処理
  • 各行の合計を maxSum と比較して最大値を更新。


5️⃣ 各列 (y方向) の合計

for (let z = 0; z < N; z++) {
  for (let x = 0; x < N; x++) {
    let sum = 0;
    for (let y = 0; y < N; y++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}

ポイント

  • XY平面の「縦一列」の合計を計算
  • イメージ:
[x][y] ← 縦方向の列
z = 前→後の層ごとに処理



6️⃣ 縦方向 (z方向) の合計

for (let y = 0; y < N; y++) {
  for (let x = 0; x < N; x++) {
    let sum = 0;
    for (let z = 0; z < N; z++) sum += cube[z][y][x];
    maxSum = Math.max(maxSum, sum);
  }
}

ポイント

  • X-Y平面で固定された位置の列を 前→後方向(z方向) に合計
  • これで立方体の「縦の列」をすべて計算できる


7️⃣ 各平面の対角線

(a) XY平面

for (let z = 0; z < N; z++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[z][i][i];           // 左上→右下
    d2 += cube[z][i][N - 1 - i];   // 右上→左下
  }
  maxSum = Math.max(maxSum, d1, d2);
}
  • XY平面ごとに 平面対角線 を計算
  • d1: 左上 → 右下
  • d2: 右上 → 左下

(b) YZ平面

for (let x = 0; x < N; x++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[i][i][x];           // 前上→後下
    d2 += cube[N - 1 - i][i][x];   // 前下→後上
  }
  maxSum = Math.max(maxSum, d1, d2);
}
  • YZ平面ごとに 縦方向と奥行きの斜め を計算

(c) ZX平面

for (let y = 0; y < N; y++) {
  let d1 = 0, d2 = 0;
  for (let i = 0; i < N; i++) {
    d1 += cube[i][y][i];           // 左奥→右手前
    d2 += cube[N - 1 - i][y][i];   // 右奥→左手前
  }
  maxSum = Math.max(maxSum, d1, d2);
}
  • ZX平面ごとに 奥行きと横方向の斜め を計算


8️⃣ 空間対角線 (立体の大対角線)

let diag1 = 0, diag2 = 0, diag3 = 0, diag4 = 0;
for (let i = 0; i < N; i++) {
  diag1 += cube[i][i][i];                   // 左上前 → 右下後
  diag2 += cube[i][i][N - 1 - i];           // 右上前 → 左下後
  diag3 += cube[i][N - 1 - i][i];           // 左下前 → 右上後
  diag4 += cube[i][N - 1 - i][N - 1 - i];   // 右下前 → 左上後
}
maxSum = Math.max(maxSum, diag1, diag2, diag3, diag4);
  • 立方体全体の 空間対角線 を計算
  • これで「立方体を通る最大のN要素の斜め列」もカバー


9️⃣ 出力

console.log(maxSum);
  • ここまでで計算した すべての縦・横・斜めの列の合計 の最大値を出力






🗒️ まとめ

  • このコードのポイントは 3次元配列を z, y, x の順で扱うこと。

  • 各平面(XY, YZ, ZX)の対角線や、立体全体の空間対角線まで網羅。

  • 入力の取り込みも 1つのループで cube[z][y][x] に格納できるので、非常に整理されている。

  • 視覚的に立方体をイメージすると「どのループでどの方向の列を足しているか」が理解しやすい。




僕の失敗談(´;ω;`)と解決法🐈

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?