はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC300のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。
A - N-choice question
a-300.rb
n, a, b = gets.split.map(&:to_i)
c = gets.split.map(&:to_i)
puts c.index(a + b) + 1
B - Same Map in the RPG World
b-300.rb
h, w = gets.split.map(&:to_i)
array_a = Array.new(h){ gets.chomp }
array_b = Array.new(h){ gets.chomp }
h.times do |s|
w.times do |t|
flag = true
h.times do |i|
w.times do |j|
- flag = false if array_a[(i - s + h) % h][(j - t + w) % w] != array_b[i][j]
+ flag = false if array_a[(i - s) % h][(j - t) % w] != array_b[i][j]
end
end
if flag
puts "Yes"
exit
end
end
end
puts "No"
解説
(公式解説を参考にしました)
(s, t)をそれぞれ0<=s<=h, 0<=t<=wの範囲で全探索していきます。このとき、配列Aを縦方向にs回シフト、横方向にt回シフトすると、A[i][j]はA[(i-s+h) % h][(j-t+w) % w]となります。そして、シフト後のAがBと一致していればYesを出力して終了、最後まで一致するものがなければNoを出力しましす。
C - Cross
c-300.rb
h, w = gets.split.map(&:to_i)
array = Array.new(h){ gets.chomp.chars.map{ |i| i == "#"} }
n = [h, w].min
ans = Array.new(n, 0)
h.times do |i|
w.times do |j|
next unless array[i][j]
d = 1
while 0 <= i - d && i + d < h &&
0 <= j - d && j + d < w &&
array[i + d][j + d] && array[i + d][j - d] &&
array[i - d][j + d] && array[i - d][j - d]
d += 1
end
ans[d - 2] += 1 if d != 1
end
end
puts ans.join(" ")
解説
(公式解説と他の方の提出結果を参考にしました)
すべてのバツ印は中央にサイズ1のバツ印を含むためdを1で初期化します。また、(i,j)(i+1,j+1)(i+1,j-1)(i-1,j+1)(i-1,j+1)すべてが#
なら、バツ印となっているためdをインクリメントします。そして、バツ印でなくなったら、対応するans配列の値をインクリメントします。なお、d-2としているのは、dを1で初期化した分とwhileループの最後の余分な分を除くためです。