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?

More than 1 year has passed since last update.

paizaラーニング レベルアップ問題集 新・Bランクレベルアップメニュー JavaScript 【配列 2】立体で計算

Last updated at Posted at 2023-02-27

【配列 2】立体で計算 (paizaランク B 相当)

考え方

三次元立体を考えた。
三次元軸の正方向を決める。
入力される値は、最初のN行が、ある二次元平面になっていると考えられる。
その二次元配列が、N個ある、と考えられる。

解答例

三次元立体をイメージする。
三次元座標を、高さh,縦(奥行)i,横(横幅)jで考えた。
高さhは上に+、縦iは手前に+,横は右に+で考えた。

縦横の和は、各平面を積み重ねるイメージで求めた。
すなわち、高さhを固定し、i,j平面の縦横の和row_sum,col_sumを求めた。これを全てのhについて繰り返す。
他の平面についても同様。

斜めについては、各平面の斜めと立方体の対角線について考えた。

各平面の斜めについて、例えば、問題文の赤矢印は、hを固定し、i,j平面の中で斜めを考えた。
他の緑、黄色矢印についても同様。

立方体の対角線の青点矢印については、4つある。
hが増えるにつれて、iが増えるup,減るdown、jが増えるup,減るdownの4通りある。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const N = Number(lines[0]);
const A = [];//高さh縦i横jの三次元配列A[h][i][j]
for (let h = 0; h < N; h++) { //高さhについて
  const A_row_col = lines.slice(h * N + 1, h * N + N + 1).map(row_col => row_col.split(" ").map(Number));//縦横の二次元配列
  A.push(A_row_col);
}

let ans = 0;//求める最大値

//縦横
//i,j平面
for (let h = 0; h < N; h++) {
  for (let i = 0; i < N; i++) {
    let row_sum = 0;//縦列
    let col_sum = 0;//横列
    for (let j = 0; j < N; j++) {
      row_sum += A[h][i][j];
      col_sum += A[h][j][i];
    }
    ans = Math.max(row_sum, col_sum, ans);
  }
}
//j,h平面
for (let i = 0; i < N; i++) {
  for (let h = 0; h < N; h++) {
    let row_sum = 0;//縦列
    let col_sum = 0;//横列
    for (let j = 0; j < N; j++) {
      row_sum += A[j][i][h];
      col_sum += A[h][i][j];
    }
    ans = Math.max(row_sum, col_sum, ans);
  }
}
//h,i平面
for (let j = 0; j < N; j++) {
  for (let h = 0; h < N; h++) {
    let row_sum = 0;//縦列
    let col_sum = 0;//横列
    for (let i = 0; i < N; i++) {
      row_sum += A[h][i][j];
      col_sum += A[i][h][j];
    }
    ans = Math.max(row_sum, col_sum, ans);
  }
}

//斜め
//i,j平面 red
for (let h = 0; h < N; h++) {
  let i_up_j_up = 0;
  let i_down_j_up = 0;
  for (let i = 0; i < N; i++) {
    i_up_j_up += A[h][i][i];
    i_down_j_up += A[h][N - 1 - i][i];
  }
  ans = Math.max(i_up_j_up, i_down_j_up, ans);
}

//j,h平面 green
for (let i = 0; i < N; i++) {
  let j_up_h_jp = 0;
  let j_down_h_up = 0;
  for (let j = 0; j < N; j++) {
    j_up_h_jp += A[j][i][j];
    j_down_h_up += A[j][i][N - 1 - j];
  }
  ans = Math.max(j_up_h_jp, j_down_h_up, ans);
}

//h,i平面 yellow
for (let j = 0; j < N; j++) {
  let h_up_i_up = 0;
  let h_down_i_up = 0;
  for (let h = 0; h < N; h++) {
    h_up_i_up += A[h][h][j];
    h_down_i_up += A[N - 1 - h][h][j];
  }
  ans = Math.max(h_up_i_up, h_down_i_up, ans);
}

//立方体の対角線 blue
let h_up_i_up_j_up = 0;
let h_up_i_up_j_down = 0; 
let h_up_i_down_j_up = 0; 
let h_up_i_down_j_down = 0; 

for (let i = 0; i < N; i++) {  
  h_up_i_up_j_up += A[i][i][i];
  h_up_i_up_j_down += A[i][i][N - 1 - i];
  h_up_i_down_j_up += A[i][N - 1 - i][i];
  h_up_i_down_j_down += A[i][N - 1 - i][N - 1 - i];
  
  ans = Math.max(
    h_up_i_up_j_up, 
    h_up_i_up_j_down, 
    h_up_i_down_j_up, 
    h_up_i_down_j_down, 
    ans
  );
  
}

console.log(ans);

解答例(C++の場合参考)

入力cinとAのところ、

入力される値cinは、最初のN行が、ある二次元平面になっていると考えられる。
その二次元配列が、N個ある三次元立体と考えられる。

Aの立方体座標i,j,kはA[i][j][k]で考え、入力cinをAに配置していく。

Aの立方体座標x,y,zはA[x][y][z]で考え、
縦、横、斜め(平面内斜め、立方体の対角線)について、和を求め、最大値を求める。

平面内の縦横斜めについて考える時は、x,y,zの一つを固定し、平面で考える。
立方体の対角線については、上の解答例と同様。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const N = Number(lines[0]);
const cin = lines.slice(1).map(line => line.split(" ").map(Number));

//縦x横y高さzの三次元配列A[x][y][z]
const A = Array(N).fill(0).map(x => x = Array(N).fill(0).map(y => y = Array(N).fill(0)));//三次元配列を初期化
for (let i = 0; i < N; i++) {
  for (let j = 0; j < N; j++) {
    for (let k = 0; k < N; k++) {
      A[i][j][k] = cin[i * N + j][k];//最初のN行が1行目の平面二次元配列
    }
  }
}

let ans = 0;//求める最大値

//縦横
  //x固定,yz平面
  for (let x = 0; x < N; x++) {
    for (let i = 0; i < N; i++) { 
      let row_sum = 0;
      for (let j = 0; j < N; j++) {
        row_sum += A[x][i][j];
      }
      ans = Math.max(row_sum, ans);
    }
  }
  //y固定,zx平面
  for (let y = 0; y < N; y++) {
    for (let i = 0; i < N; i++) {
      let row_sum = 0, col_sum = 0;
      for (let j = 0; j < N; j++) {
        row_sum += A[i][y][j];
        col_sum += A[j][y][i];
      }
      ans = Math.max(row_sum, col_sum, ans);
    }
  }
  //z固定、xy平面
  for (let z = 0; z < N; z++) {
    for (let i = 0; i < N; i++) {
      let row_sum = 0, col_sum = 0;
      for (let j = 0; j < N; j++) {
        row_sum += A[i][j][z];
        col_sum += A[j][i][z];
      }
      ans = Math.max(row_sum, col_sum, ans);
    }
  }

//斜め
  //x固定,yz平面
  for (let x = 0; x < N; x++) {
    let left_right_down = 0, left_right_up = 0;
    for (let i = 0; i < N; i++) {
      left_right_down += A[x][i][i];
      left_right_up += A[x][N - 1 - i][i];
    }
    ans = Math.max(left_right_down, left_right_up, ans);
  }
  //y固定,zx平面
  for (let y = 0; y < N; y++) {
    let left_right_down = 0, left_right_up = 0;
    for (let i = 0; i < N; i++) {
      left_right_down += A[i][y][i];
      left_right_up += A[N - 1 - i][y][i];
    }
    ans = Math.max(left_right_down, left_right_up, ans);
  }
  //z固定、xy平面
  for (let z = 0; z < N; z++) {
    let left_right_down = 0, left_right_up = 0;
    for (let i = 0; i < N; i++) {
      left_right_down += A[i][i][z];
      left_right_up += A[i][N - 1 - i][z];
    }
    ans = Math.max(left_right_down, left_right_up, ans);
  }

//立方体の対角線 blue
 let l_1 = 0, l_2 = 0, l_3 = 0, l_4 = 0;

  for (let i = 0; i < N; i++) {
    l_1 += A[i][i][i];
    l_2 += A[i][N - 1 - i][N - 1 - i];
    l_3 += A[i][N - 1 - i][i];
    l_4 += A[i][i][N - 1 - i];
  }

  ans = Math.max(ans, l_1, l_2, l_3, l_4);

//出力
console.log(ans);
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?