日別アーカイブ: 2022年10月19日

TIPS(Ruby:表から移動時間の総和を出す)

目標:なにがしたいか?

表から移動時間の総和を出す

問題

行きたいポイントがリストで与えられるので、与えられた順に各ポイントを訪れた際どれくらい時間がかかるのか求めてください。最初のポイントで始めるところから時間を計るものとします。

入力例1の場合、以下のように、各ポイントの移動時間が与えられています。

各ポイント

1

2

3

 

各ポイント\各ポイント

1

2

3

1

0

3

4

2

3

0

5

3

4

5

0

ポイント 1 でポイントから 2 に移動するのに時間 3 かかります。
ポイント 2 でポイントから 3 に移動するのに時間 5 かかります。
ポイント 3 でポイントから 1 に移動するのに時間 4 かかります。
全部で時間 12 かかります。

入力される値
入力は以下のフォーマットで与えられます。

N
c_{1, 1} c_{1, 2} ... c_{1, N}
c_{2, 1} c_{2, 2} ... c_{2, N}
...
c_{N, 1} c_{N, 2} ... c_{N, N}
K
y_1
y_2
...
y_K
  • ・1 行目に全てのポイントの数を表す整数 N が与えられます。
  • ・続く N 行のうちの i 行目 (1 ≦ i ≦ N) には N 個の整数が半角スペース区切りで与えられます。i 行目の j 番目 (1 ≦ j ≦ N) の整数 c_{i, j} は i 番目のポイントから j 番目のポイントへの移動時間を意味します。
  • ・続く 1 行には、行きたいポイントの数を表す整数 K が与えられます。
  • ・続く K 行のうちの i 行目 (1 ≦ i ≦ K) には、i 番目に訪れたいポイントを表す整数 y_i が与えられます。
  • ・入力は合計で 2 × N + K + 2 行となり、入力値最終行の末尾に改行が 1 つ入ります。
期待する出力
・全行動後にかかる時間を整数で出力してください。
・末尾に改行を入れ、余計な文字、空行を含んではいけません。
条件
すべてのテストケースにおいて、以下の条件をみたします。

・1 ≦ N ≦ 100
・各 i, j (1 ≦ i, j ≦ N) について
 ・1 ≦ c_{i, j} ≦ 100 (i ≠ j)
 ・c_{i, j} = 0 (i = j)
 ・c_{i, j} = c_{j, i} (i ≠ j)
・1 ≦ K ≦ 100
・1 ≦ y_i ≦ N (1 ≦ i ≦ K)
入力例1
3
0 3 4
3 0 5
4 5 0
4
1
2
3
1
出力例1
12
入力例2
4
0 2 9 5
2 0 8 2
9 8 0 3
5 2 3 0
5
1
2
1
3
1
出力例2
22

解答と解説 入力例1で解説

each_consを使えばいとも簡単に解くことができる
移動時間の処理を書く。
配列は0から始まるので全体を-1する
(move.map { |a| a – 1 })
あとは移動時間を加算してあげれば良い

#空の配列で初期化する 
chart,move,ary= [],[],[],[]
#1行目の入力値(数値)を変数に代入する
n = gets.to_i

#n回繰り返し入力値を受け取り配列に代入する
n.times { chart << gets.split.map(&:to_i) }

#全体の時間を司る変数を作成して0で初期化する
total_minutes = 0

#入力値(数値)を変数に代入する
k = gets.to_i

#n回繰り返し入力値を受け取り配列に代入する
k.times.map { move << gets.to_i }

#k回繰り返す
k.times do |i|

# 配列は0から始まるので全体を-1するmove.map { |a| a - 1 }
# [[0, 1], [1, 2], [2, 0]]のような配列を作り次に使えるようにする
# ↑.each_cons(2).map { |x| x } if i == 0
  ary = move.map { |a| a - 1 }.each_cons(2).map { |x| x } if i == 0
# 全体の時間に加算していく
  total_minutes += chart[ary[i][0]][ary[i][1]] if i + 1 != k
end
# 出力する
puts total_minutes

※動作について(k.times do |i|)からend

1回目のループ

ポイント1から2に移動する→配列は0からなのでchart[ary[i][0]][ary[i][1]]の場合

ary = [[0, 1], [1, 2], [2, 0]]

ary[0] = [0,1]

[ary[0][0]] = 0

[ary[0][1]] = 1

chart[ary[0][0]][ary[0][1]] = chart[0][1]

chart = [[0, 3, 4], [3, 0, 5], [4, 5, 0]]

chart[0][1] = 3

total_minutes += 3

total_minutes は3になる

2回目のループ

ポイント2から3に移動する→配列は0からなのでchart[ary[i][0]][ary[i][1]]の場合

ary = [[0, 1], [1, 2], [2, 0]]

ary[1] = [1,2]

[ary[1][0]] = 1

[ary[1][1]] = 2

chart[ary[1][0]][ary[1][1]] = chart[1][2]

chart = [[0, 3, 4], [3, 0, 5], [4, 5, 0]]

chart[1][2] = 5

total_minutes += 5

total_minutes は8になる

3回目のループ

ポイント3から1に移動する→配列は0からなのでchart[ary[i][0]][ary[i][1]]の場合

ary = [[0, 1], [1, 2], [2, 0]]

ary[2] = [2,0]

[ary[2][0]] = 2

[ary[2][1]] = 0

chart[ary[2][0]][ary[2][1]] = chart[2][0]

chart = [[0, 3, 4], [3, 0, 5], [4, 5, 0]]

chart[2][0] = 4

total_minutes += 4

total_minutes は12になる

if i + 1 != k  により4回目のループはないので終わりになる

よって全体の移動時間が12となる