今日プロ 見えない誤差にも気をつけよ
本記事は、筆者が学習していく中で、
「この考え、大事だな」と思ったものを記事にしたものです。
皆さんの学習の助けになれば幸いです。
本日のトピック
AtCoder 189のB問題 Alcoholic
AtCoder 189のB問題 Alcoholic
ふむふむ。どうやらx から v*p/100 を引き算し続けて、xの値が0を下回ったら、breakすれば行けそう。
ということで書いたコード
n, x = map(int, input().split())
alcohol_list = []
for i in range(n):
a, b = map(int, input().split())
alcohol = a*b/100
alcohol_list.append(alcohol)
count = 0
flg = 0
for i in alcohol_list:
if x >= 0:
count += 1
x -= i
print(x)
elif x < 0:
break
if x < 0:
print(count)
else:
print(-1)
vscode上では問題なく、動いたので、そのまま提出すると・・・
【WA】間違っているよ
(´;ω;`)
自分のコードに欠陥があるのかと思い、様々なパターン境界値分析や同値分割方をしたけど、わからない・・・
全パターン網羅できてないんか?
ということで、公式の解説を見てみることに
公式解説
浮動小数点数の演算は一般に誤差を含みます。例えば、・・・
なるほど・・・今回のエラー原因は、浮動小数点の演算で生じる誤差が原因らしい。
このような問題を避ける最も簡単な方法は、整数のみで計算できるように適切な式変形を行うことです。
今回の場合、両辺に100を掛けることで整数のみで計算できます。
参考文献
なるほど。早速int型(整数)で計算することに
回答コード
n, x = map(int, input().split())
alcohol_list = []
for i in range(n):
a, b = map(int, input().split())
alcohol = a*b
alcohol_list.append(alcohol)
count = 0
flg = 0
x *= 100
for i in alcohol_list:
if x >= 0:
count += 1
x -= i
elif x < 0:
break
if x < 0:
print(count)
else:
print(-1)
今回、小数点が出てくると言っても、せいぜい少数第2位までしか出てこないから大丈夫だと思ってました。それよか自分のコードに欠陥があって全パターン網羅できていないと思ってた。WAが6個もあったし。
本当にAtcoderをやり始めてからは、コードを書く際にいろんなことを考えるようになりました。まだまだ未熟者ですが、これからもがんばりますので、応援していただけると嬉しいです!!
この記事が気に入ったらサポートをしてみませんか?