##はじめに
AtCoder過去問でA問題ですが、小さな見落としでかなり悩みました。
私がつまづいたところも含めて解説していきたいと思います。
よろしくお願いします。
問題はこちらから確認してください↓
A - Cookie Exchanges
今回はA問題ということで比較的初学者でも時間をかければそれなりに答えを出せるのではないのでしょうか。
こちら私がはじめに組んだプログラムです。
(このコードは間違っています。どこが間違っているか探して見てください)↓
a, b, c = gets.split.map(&:to_i)
count = 0
if a == b && b == c
puts -1
else
while a.even? && b.even? && c.even?
a_half = a/2
b_half = b/2
c_half = c/2
a = b_half + c_half
b = a_half + c_half
c = a_half + b_half
count += 1
end
puts count
end
1行目で入力を受け取ります。
続いて最終的に答えとなる変数count(クッキーを交換した回数)を用意して0を代入しておきます。
if文の中身を解説します。
まず、無限に処理をしてしまうものを除外し、問題に従って-1
を出力するようにします
if a == b && b == c
puts -1
a, b, cが同じ数字だった場合、abcのどれも奇数になることは永遠にないからです。
条件分岐ができたら、上記のもの以外はwhile文でぶんまわし、最終的にwhileの条件式から外れたときに何回まわしたかが答え(クッキーを交換した回数)になります。
else
while a.even? && b.even? && c.even?
a_half = a/2
b_half = b/2
c_half = c/2
a = b_half + c_half
b = a_half + c_half
c = a_half + b_half
count += 1
end
puts count
end
whileの条件式はa, b, cのいずれかが奇数になるまで繰り返してくださいってことです。
処理内容は問題文を読めばすぐに納得していただけると思いますが、一応解説すると。
クッキーの交換の仕方は
まずa(高橋), b(青木), c(すぬけ)の持っているクッキーの個数を半分にします。
aはb, cに半分ずつ渡す。
bはa, cに半分ずつ渡す。
cはa, bに半分ずつ渡す。
これが交換一回の処理です。誰か一人でも手持ちのクッキーが奇数になったら交換終了になるので、それまで繰り返すという処理です。
##解答
私の回答で間違っていたのはif文の条件式です。
私のif文をもう一度見てみます。
if a == b && b == c
これはa, b, cが全て同じ数字なら無限にクッキーを交換してしまうので、無限に交換するときの条件式を書いて、-1
を出力しています。
しかしながら、無限に交換するのは、同じ数字且つ偶数の時
なのです。
全部奇数だったら交換すらできないので0
を出力しなくてはいけないのですね。
なので下記のように、条件を追加します。
if a == b && b == c && a.even?
これで全て奇数の時はelseの処理に振られ、count=0という結果を得られます。
a, b, c = gets.split.map(&:to_i)
count = 0
if a == b && b == c && a.even?
puts -1
else
while a.even? && b.even? && c.even?
a_half = a/2
b_half = b/2
c_half = c/2
a = b_half + c_half
b = a_half + c_half
c = a_half + b_half
count += 1
end
puts count
end
##最後に
A問題だからと舐めてかかって、かなり悩みました。
入力値に何を入れたときに間違った解答になったのかを教えてくれたらもっと早く気づけるのに。。。