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$ より大きいと誤差吸収する方針でも解ける。
(コード例なし)