見出し画像

今日プロ 見えない誤差にも気をつけよ

本記事は、筆者が学習していく中で、
「この考え、大事だな」と思ったものを記事にしたものです。
皆さんの学習の助けになれば幸いです。

本日のトピック

AtCoder 189のB問題 Alcoholic

本日の問題はこちら

AtCoder 189のB問題 Alcoholic

スクリーンショット 2021-07-19 175336

ふむふむ。どうやら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をやり始めてからは、コードを書く際にいろんなことを考えるようになりました。まだまだ未熟者ですが、これからもがんばりますので、応援していただけると嬉しいです!!



この記事が気に入ったらサポートをしてみませんか?