はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC259のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。
A - Growth Record
a-259.rb
n, m, x, t, d = gets.split.map(&:to_i)
puts x <= m ? t : t - ((x - m) * d)
解説
X歳からN歳までは身長は変わらないので、X<=MであればそのままTを出力します。一方、M<Xであれば、X-M回分Dcm伸びた結果Tcmになったということを考え、計算することで答えを求めることができます。
B - Counterclockwise Rotation
b-259.rb
a, b, d = gets.split.map(&:to_i)
r = Math.sqrt(a ** 2 + b ** 2)
theta = Math.atan2(b, a)
theta += d * Math::PI / 180
puts "#{r * Math.cos(theta)} #{r * Math.sin(theta)}"
別解
a, b, d = gets.split.map(&:to_i)
theta = d * Math::PI / 180
puts "#{a * Math.cos(theta) - b * Math.sin(theta)} #{a * Math.sin(theta) + b * Math.cos(theta)}"
解説
(公式解説を参考にしました)
距離を求め、逆三角関数から角度を求めます。そして、dをラジアンに変換して角度θに足し、sin、cosを使うことで移動後の点を求めることができます。
C - XX to XXX
c-259.rb
# 修正前
def f(str)
array = []
count = 1
str.size.times do |i|
if str[i] != str[i + 1]
array << [str[i], count]
count = 0
end
count += 1
end
return array
end
s = gets.chomp
t = gets.chomp
ss = f(s)
tt = f(t)
if ss.size != tt.size
puts "No"
exit
end
ss.size.times do |i|
if ss[i][0] != tt[i][0]
puts "No"
exit
else
if (ss[i][1] == 1 && tt[i][1] > 1) || ss[i][1] > tt[i][1]
puts "No"
exit
end
end
end
puts "Yes"
c-259.rb
# 修正後
def f(str)
array = []
str.scan(/((.)\2*)/).each { |factor| array << [factor[1], factor[0].size] }
return array
end
s = gets.chomp
t = gets.chomp
ss = f(s)
tt = f(t)
if ss.size != tt.size
puts "No"
exit
end
ss.zip(tt).each do |factor1, factor2|
if factor1[0] != factor2[0] || factor1[1] > factor2[1] || (factor1[1] == 1 && factor2[1] != 1)
puts "No"
exit
end
end
puts "Yes"
解説
(公式解説を参考にしました)
最初に、連続する文字で同じものの数(例えば、aaaならa3)に置き換えるメソッドを定義します。そして、条件として「文字が一致しているか」「ssにおけるそれぞれの文字数がttにおけるそれぞれの文字数を超えていないか」を調べることで実装することができます。