[blogcard url=http://abc037.contest.atcoder.jp/tasks/abc037_a]

AtCorder Begginer Contestの37の饅頭の問題を解いたので、ここで学んだことを振り返ります。

まず、問題は、

問題文
あなたは饅頭の店に来ています。ここでは白と緑の 2 種類の饅頭が売られていて、それぞれの種類は何個でも買うことができます。 白色の饅頭は 1 個 A 円で、緑色の饅頭は 1 個 B 円です。
あなたは C 円持っています。あなたはとにかく沢山の個数を食べたいので、種類は気にせず、なるべく多くの個数の饅頭を買おうと思っています。 2 種類で買う個数が違ったり、片方の種類しか買わなかったりしてもかまいません。
最大で何個の饅頭が買えるでしょうか。

というものです。
これに成約が加わります。

1≤A,B≤1,000
1≤C≤1,000,000

入力は以下の形式で標準入力から与えられる。
A B C

入力例 1
3 5 6

出力例 1
2

つまり、AもBも1〜1000までで、お金Cは1〜1000,000までとなります。
そこで、私は色々調べて、下記のようなコードを記載して、100点を取ることができました。
※AtCoderではコードを提出すると、自動的にテストが走り、点数が表示される。

[code]
A, B, C = gets.split.map { | v |
v.to_i
}

if A.between?(1,1000) && B.between?(1,1000) && C.between?(1,1000000)
if A <= B
NUM = C / A
else
NUM = C / B
end
puts NUM
end
[/code]

前半部分について

まず、標準入力にもいくつかありますが、AtCoderではファイルからの標準入力となります。
なので、getsメソッドを使用することで、ファイルからの標準入力を取得します。
次に、splitメソッドで文字列を分割します。
最後にmapメソッドで、その個数文だけ、{}の中のコードを実行します。
今回の場合は、ファイルからの文字列をto_iで整数として定義しています。
これらの値をABCそれぞれに代入しているのが前半部分です。

後半部分について

後半部分について、私はこう考えました。
まず、between?(NUM1,NUM2)メソッドでは、NUM1とNUM2の間かどうかの真偽値を取得するメソッドだそうです。
なので、AとBとC、それぞれの範囲をbetweenで定義して、&&条件にし、それに合致したら、、というロジックにしました。

そして、今回必要な解は、持っているお金Cに対して、饅頭が買える最大数です。
つまり、金額が安い方の饅頭であれば、持ち金Cで沢山買えることに気が付きました。
なので、AとBの値を比較して、BよりもAが小さい場合は、CをAで割る。
そして、AとBの値を比較して、BよりもAが大きい場合は、CをBで割る。
最後に、AとBの値を比較して、BもAも同じ値だったら、CをAで割る。
と考えました。
最初と最後はAがB以下だった場合、とできるので一緒にし、上記コードとなりました。

betweenの個所が冗長な感じであることと、ifが入れ子構造になっているので、この辺は改善していきたいなと思います。

以上、解けると楽しいAtCoderの振り返りでした。

カテゴリー: Ruby