Open paraizo2424 opened 1 year ago
入力値例(S=スタート位置、G=ゴール位置、#=進行不可or探索済み、.=未探索)
7 6
######
.....#
####.#
#.S#.#
#.##.#
##.G.#
######
h, w = gets.split.map(&:to_i)
maps = h.times.map{gets.chomp.chars.unshift('#').push('#')}
maps.unshift(Array.new(w + 2, '#')).push(Array.new(w + 2, '#'))
pos_que = Queue.new
# 初期位置の検索
(1..h).each do |y|
(1..w).each do |x|
pos_que.enq({y: y, x: x}) if maps[y][x] == 'S'
end
end
goal_flug = false
while !pos_que.empty?
pos = pos_que.deq
# 探索済み'#'に変更
maps[pos[:y]][pos[:x]] = '#'
# 上下左右のマス
[-1, 1].each do |i|
x = pos[:x] + i
if maps[pos[:y]][x] == '.'
pos_que.enq({x: x, y: pos[:y]})
elsif maps[pos[:y]][x] == 'G'
goal_flug = true
end
y = pos[:y] + i
if maps[y][pos[:x]] == '.'
pos_que.enq({x: pos[:x], y: y})
elsif maps[y][pos[:x]] == 'G'
goal_flug = true
end
end
break if goal_flug
end
puts goal_flug ? 'YES' : 'NO'
参考サイト
Ruby競プロTips(基本・罠・高速化108 2.7x2.7)
入力
半角区切りの数値(例:"1 2 3 4") gets.split.map(&:to_i)
区切りのない数値(例:"1234") gets.split('').map(&:to_i)
2次元配列へ入力 boards = h.times.map{gets.split.map(&:to_i)}
多重代入(入力値: "3 abc") n, str = gets.split
文字列を文字ごとの配列に格納(入力値: "ABCDE") ary = gets.chomp.chars
配列 Array
初期化
2次元配列の初期化(高さh、幅w) maps = h.times.map{Array.new(w, 0)}
深いコピー
a = [[1, 2], [3, 4]] b = a s = a.dup # 浅いコピー: 複製元と同一要素を参照し、要素まで複製してません。 d = a.map(&:dup) # 深いコピー
ソート
昇順並び替え(数値、文字) ary.sort!
降順並び替え(数値、文字) ary.sort.reverse!
2次元配列の昇順並び替え ary.sort_by!{|ary| ary[0]}
2次元配列の降順並び替え ary.sort_by!{|ary| -ary[0]}
操作
最後尾に追加 ary << 1 ary.push(1)
最後尾の要素を削除 ary.pop
先頭に追加 ary.unshift(1)
先頭を削除 ary.shift
置換 ary.map!{|x| x=="bar" ? "hoge" : x}
便利なメソッド
tallyでの要素数の数え上げ p ["c", "a", "b", "b", "b", "b", "c"].tally #=> {"c"=>2, "a"=>1, "b"=>4}
injectですべての要素の演算 array.inject(:) => 総乗 array.sum => 総和 array.inject(3,:) #初期値3に対して、配列の要素をすべて掛ける array.inject(100,:-) #100からarrayの合計値を引く
入れ替え
入れ替え m, n = n, m
マス目の問題
上下左右のマス目の確認
出力
三項演算子 puts x == 0 ? "Yes" : "No"
改行しない出力 print str
2次元配列の出力 maps = [[1, 2], [3, 4]] puts maps.map(&:join) 12 34