※スキルチェック問題ではありません。
規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。
詳しくはコチラ
なるべくわかりやすい解説を付けました。
FINAL問題 行によって長さが違う二次元配列の表示】すべての行の長さと値が不定な 2 次元配列の出力 (paizaランク B 相当)
自然数 N, M と N 個の自然数からなる数列 A と M 個の自然数からなる数列 B が与えられます。1 行目には数列 A の最初の B_1 個の値を出力し、 2 行目にはその次から B_2 個の値を出力します。このように、i 行目には数列 A の 1 + B_1 + B_2 + … + B_{i – 1} 番目の値から B_i 個の値を出力してください。言い換えると、数列 A の値を B_1 個、B_2個、… B_M 個で分割し、それぞれの数列を改行区切りで出力してください。
- 入力される値
-
N M A_1 A_2 A_3 ... A_N B_1 B_2 B_3 ... B_M
入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。
- 期待する出力
- 答えの数値を出力してください。
A_1 ... A_{B_1} A_{B_1+1} ... A_{B_1+B_2-1} A_{B_1+B_2} ... A_{B_1+B_2+B_3-1} ... A_{B_1+...+B_{M-1}} ... A_{B_1+B_2+...+B_M}
末尾に改行を入れ、余計な文字、空行を含んではいけません。
- 条件
- すべてのテストケースにおいて、以下の条件をみたします。
* N, Mは 1 以上 100 以下
* M ≦ N
* A, Bの各要素の値は 1 以上 100 以下
* B_1 + B_2 + B_3 + … + B_M = N
- 入力例1
-
10 4 1 2 3 4 5 6 7 8 9 10 2 6 1 1
- 出力例1
-
1 2 3 4 5 6 7 8 9 10
- 入力例2
-
1 1 1 1
- 出力例2
-
1
解答 (入力例1で解説)
# 1行目の半角スペース刻みの入力値を各変数に代入 n,m = gets.split.map(&:to_i) # 2行目の半角スペース刻みの入力値を配列として変数に代入 numbers = gets.split.map(&:to_i) # 3行目の半角スペース刻みの入力値を配列として定数に代入 B = gets.split.map(&:to_i) #変数に初期値を代入(理由は後述) count = 0 #m回繰り返す m.times do |i| # 計算しやすいように変数に代入する(やらなくてもOK) x = B[i] # 配列のnumbersの出力範囲をきめて出力する(このとき半角スペースを間に挟む) #※解説は後述 puts numbers[count..(count + x - 1)].join(' ') # countにxを加算することで次のループの最初の地点を設定する count += x end
※ポイント
iは0からはじまる
1回目のループ
puts numbers[count..(count + x – 1)].join(‘ ‘)
↓
puts numbers[0..1].join(‘ ‘)となるので
1 2が出力されて
count に 2が加算され2になる(B[0] = 2 なので)
2回目のループ
puts numbers[count..(count + x – 1)].join(‘ ‘)
↓
puts numbers[2..7].join(‘ ‘)となるので
3 4 5 6 7 8が出力されて
count に 6が加算され8になる(B[1] = 6 なので)
3回目のループ
puts numbers[count..(count + x – 1)].join(‘ ‘)
↓
puts numbers[8..8].join(‘ ‘)となるので
9が出力されて
count に 1が加算され9になる(B[2] = 1 なので)
4回目のループ
puts numbers[count..(count + x – 1)].join(‘ ‘)
↓