はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC250のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。
A - Adjacent Squares
a-250.rb
h, w = gets.split.map(&:to_i)
r, c = gets.split.map(&:to_i)
puts [1 - r, 1 - c, r - h, c - w].count{ _1 < 0 }
解説
求める答えは、1 < R
, 1 < C
, R < H
, C < W
の4つの条件を与えられたR, Cがいくつ満たしているかと同値になるので、count
メソッドを使って数え上げることで解くことができます。
B - Enlarged Checker Board
b-250.rb
n, a, b = gets.split.map(&:to_i)
n.times do |i|
array = []
n.times do |j|
(i + j).even? ? array << "." * b : array << "#" * b
end
a.times{ puts array.join }
end
参照する形にする。
別解
n, a, b = gets.split.map(&:to_i)
strs = ["." * b, "#" * b]
n.times do |i|
array = []
n.times do |j|
array << strs[(i + j) % 2]
end
a.times{ puts array.join }
end
他の方の提出結果を拝見したところ、上記コードはもう少し簡素に書けるようです。
b-250.rb
n, a, b = gets.split.map(&:to_i)
puts (1..n).map{ |i| [(1..n).map{ |j| ((i + j).odd? ? "#" : ".") * b }.join] * a}
解説
0から始まるオフセットで考えると、(0, 0)が白いマスであることからi+j
が偶数となるところが.
となり、奇数となるところが#
となることが分かります。後は、aとb分適宜マスを増やせば答えが求まります。
C - Adjacent Swaps
c-250.rb
n, q = gets.split.map(&:to_i)
ans = [*1..n]
index_of_ball = n.times.to_h{ |i| [i + 1, i] }
q.times do
x = gets.to_i
base = next_to = index_of_ball[x]
next_to += (next_to == n - 1) ? -1 : 1
ans[base], ans[next_to] = ans[next_to], ans[base]
index_of_ball[ans[base]], index_of_ball[ans[next_to]] = index_of_ball[ans[next_to]], index_of_ball[ans[base]]
end
puts ans.join(" ")
別解
n, q = gets.split.map(&:to_i)
ans = [*1..n]
index_of_ball = n.times.to_h{ |i| [i + 1, i] }
q.times do
x = gets.to_i
base = index_of_ball[x].clamp(..n - 2)
x, y = (ans[base, 2] = ans[base + 1], ans[base])
index_of_ball[x], index_of_ball[y] = index_of_ball[y], index_of_ball[x]
end
puts ans.join(" ")
解説
(公式解説を参考にしました)
答えとなる配列を[*1..n]
で初期化するとともに、ボールがどこにあるかを記録する連想配列を用意します。そして、問題文の通りに配列とボールの位置の情報を更新していくことで本問題は解くことができます。