😀

AtCoder Beginners SelectionをRubyでやってみた振り返り

2021/09/28に公開

#まえがき
 AtCoderに登録したはいいものの、何から始めていいかわからなかったので、とりあえずn番煎じだと思うがAtCoder Beginners SelectionRubyで解いてみた。せっかくの休日丸々暇だったのでその振り返りをする。(なおコードはガバガバな模様。変数名がね…)
 10問全体の所要時間は約4時間()。Beginner Contestが1時間40分/4問なのでまだまだ精進が足りてませんね...

#回答時のコード
 ここから大体見れる。
 RE(Runtime Error)とWA(Wrong Answer)出しまくっている。
##1, ABC086A - Product

b_c = gets.split
b,c = b_c[0].to_i, b_c[1].to_i
d = b * c
if d % 2 == 0
  print("Even\n")
else
  print("Odd\n")
end

正の2整数の積が偶数か奇数かを求める問題。
 最初にsplitしておきながらすぐさま別変数に分け直すガバ-114514点
##2, ABC081A - Placing Marbles

num = gets.chomp.scan(/[0-9]{1}/)
app = 0
num.each {|zoo|
  if zoo == "1"
    app += 1
  end
}
puts app

0か1、が並んだ3桁数の1の数を数える問題。
 zooってなんだよ… "zero or one"的な意味を持たせたかったんでしょうね…
##3, ABC081B - Shift only

numnum = gets.chomp.to_i
nums = gets.chomp.split
aan = 0
while true
for aaa in 0..numnum-1
  unless nums[aaa].to_i.even?
    puts aan
    exit
  else
    nums[aaa] = nums[aaa].to_i / 2
  end
end
aan += 1
end

3整数が共に何回2で割れるかを求める問題。
 aanaaaが併存していてなんとも読みづらい…
##4, ABC087B - Coins

c_500 = gets.chomp.to_i
c_100 = gets.chomp.to_i
c_50 = gets.chomp.to_i
summ = gets.chomp.to_i
aaaa = 0
for a in 0..c_500
  for b in 0..c_100
    for c in 0..c_50
      if (a*500) + (b*100) + (c*50) == summ
        aaaa += 1
      end
    end
  end
end
puts aaaa

指定枚数のある500円、100円、50円の硬貨で指定金額を丁度払える組み合わせの数を求める問題。
 for文がネストしすぎている。もっとeach使ってeach使ってホラ
##5, ABC083B - Some Sums

a = gets.chomp.split
ans = 0
for aa in 1..a[0].to_i
aaa = aa.to_s.scan(/[0-9]{1}/).map { |aaaa| aaaa.to_i }.inject(:+)
  if aaa >= a[1].to_i && aaa <= a[2].to_i
    ans += aa
  end
end
puts ans

1以上N以下の整数のうち、10進法での各桁の和がA以上B以下であるものの総和(原文ママ)を求める問題。
 ここでmapで配列内の全要素をint型に変えることに気付いたようですね。
##6, ABC088B - Card Game for Two

a = gets.chomp.to_i
b = 0
bb = 0
cards = gets.chomp.split.map{|x| x.to_i}.sort
for aa in 0..a-1
  if aa.odd?
    b += cards[aa]
  else
    bb += cards[aa]
  end
end
puts (bb-b).abs

ある長さの整数列をソートして偶数番と奇数番の合計の差を取った時の絶対値を求める問題。
 要約してしまえば単純だけど、問題文が回りくどい。
##7, ABC085B - Kagami Mochi

a = gets.chomp.to_i
rice = []
for aa in 0..a-1
  rice[aa] = gets.chomp.to_i
end
puts rice.sort.uniq.size

整数群の重複した数を除き大きい順に並べた時の数の個数を求める問題。
 ぶっちゃけ配列にぶち込んで重複省いた時点でソートする必要は皆無。sortくん要らないですねこれは…
##8, ABC085C - Otoshidama

n = gets.chomp.split.map {|nn| nn.to_i}
for a in 0..n[0]
 for b in 0..n[0]-a
  c = n[0]-a-b
    if a+b+c==n[0] && 10000*a+5000*b+1000*c == n[1]
     puts [a,b,c]*" "
     exit
    end
  end
end
puts "-1 -1 -1"

指定枚数のある10000円、5000円、1000円の紙幣で指定金額を丁度払える「組み合わせ」を求める問題。
 4の計算量マシマシバージョン。TLE(Time limit Exceeded)で幾度となく弾かれた。実行時間短縮のためにfor回す範囲を狭めたら通った。こんなんでいいのかよ!
##9, ABC049C - 白昼夢 / Daydream

a = gets.chomp.to_s
a.gsub!(/erase(r){0,1}/, "")
a.gsub!(/dreamer/, "")
a.gsub!(/dream/, "")
if a == ""
  puts "YES"
else
  puts "NO"
end

与えられた単語を指定の4単語(dream dreamer erase eraser)の連続で表現可能か判定する問題。
 最初はdreameraserとかを考慮して無かったせいでガンガン弾かれてあ^~ぱらぱらり~になった。
##10, ABC086C - Traveling

a = gets.chomp.to_i
b = [[0,0,0]]
a.times do
  c = gets.chomp.split.map{|cc|cc.to_i}
  b.push(c)
end
for d in 0..a-1
  unless (b[d+1][0]-b[d][0]) >= ((b[d+1][1]-b[d][1]).abs + (b[d+1][2]-b[d][2]).abs) && (b[d+1][0]-b[d][0]) %2 == ((b[d+1][1]-b[d][1]).abs + (b[d+1][2]-b[d][2]).abs) %2
    puts "No"
    exit
  end
end
puts "Yes"

二次元の整数格子(第一象限)を原点からt+1時間毎常に1進む時、与えられた時間で同じく与えられた座標に移動可能か判定する問題。
 すぐには題意を理解出来ませんでした…一時間ぐらい紙に書いてようやく理解。
##まとめ
 振り返ってみて、結構ガバガバなところが散見されますね
 これからも…精進します…

GitHubで編集を提案

Discussion