ABC465 A - Supermajority

超多数派

考え方

入力は整数が $2$ つなので、int 型の変数を $2$ つ用意し、cin で入力を受け取る。

さて、$A>B \times \dfrac{2}{3}$ かどうかを if 文で書けばよいように思える。
しかし、割り算を用いる比較は、プログラムの仕様上の落とし穴が $2$ つある。

まず $1$ つめに、単純に $3$ で割ると、整数同士の割り算で商だけ求める計算になってしまう。
例えば $B=7$ の場合、$7$ に $2$ をかけて $14$、それを $3$ で割って $4$、とされて余りの $2$ が捨てられてしまう。

では、$3.0$ で割って小数で判定する場合はどうかというと、今度は $2$ つめの罠が待っている。
小数は適当なところで計算を打ち切るため、$3.0$ が内部で $3.0000000000000001$ になっていたりする。
そのせいで、小数の大小比較は、本来同じはずの値を「左が小さい」などと誤判定することがある。

ということで、両方の罠を避けるため、そもそも割り算も小数も避けて、整数で比較できるようにする。
条件式の両辺に $3$ をかけても問題ないため、「$3A>2B$ であるかどうか?」を if 文の判定に使えばよい。
ここさえ書けたら、あとは if 文の中で出力する文字を決めるだけである。

if 文の中で直接 cout してもいいし、事前に出力用文字列を用意してもよい。

実は今回は、ちゃんと $2$ をかけてから $3$ で割る順序なら、どちらの罠も自然に回避されて AC する。
とはいえ次もそうだとは限らない。
「割り算の結果で比較することは避ける」を意識することは大切である。

入力例1での動作

入力を受け取る。

a: 316
b: 465

答え用の変数 result"No" で初期化する。

result: "No"

3*a>2*b かどうかを判定する。

3*a: 948
2*b: 930

3*a>2*b が成り立つので、result"Yes" にする。

result: "Yes"

最後に、result を出力すればよい。

注意点

特になし。

別解

今回、非整数になる場合のズレ方は必ず $\dfrac{1}{3} = 0.333\dots$ 単位である。
よって、小数で計算し、$A$ が $B \times \dfrac{2}{3}+0.1$ より大きいと誤差吸収する方針でも解ける。
(コード例なし)