0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AGC041

Last updated at Posted at 2019-12-28

AGC041に参加しました。

結果は0完。。。

A問題

方針としてはAとBの差が
偶数の時は、お互いに近づけばいいだけなので差分を2で割った商が答えで、
奇数の時はA,Bの近い方の端っこに行ってA,Bの差分を偶数に調整してからお互い近づけば良いので

公式の解答にある通り

$$ min(A-1, N-b) + 1 + \frac{b-a-1}{2} $$

が答えになります。
ここまでわかった。

が、通らなかった。

以下が通らなかったコード

n, a, b = (int(i) for i in input().split())

x = b-a
if ((x % 2) == 0):
    print(int(x/2))
    exit()
else:
    print(min(a-1, n-b) + int((x+1)/2))
    exit()

何が悪かったか?

int(x/2)が問題でした。

なるほど。
それで、数が大きいと除算演算子/が精度が悪くなるのはわかったけど、どこまで大きいくなると精度が落ちるのか?

倍精度浮動小数点では、64ビットを使って数を表現し、その内訳は次のとおりである。

符号ビット (sign): 1 ビット
指数部 (exponent): 11 ビット
仮数部 (fraction): 52 ビット
精度を求める上で重要なのは仮数部のビット数 = 52ビットである。これに加えて、「最上位ビットは1に決まってるんだから書かなくてもいいでしょ、省略するわ」という省略された1ビット(ケチ表現)がある。合計53ビットがdouble型の精度となり、10進に直した精度は53 * log10 2 =15.95桁となる。

つまり、float型の精度は約16桁である。これより高い精度は表現できない。
https://linus-mk.hatenablog.com/entry/2019/05/26/234642

16桁くらいまでしか精度を保てないとのことでした。

ということで、除算結果を不動小数点にしない//で切り捨て除算を行えばOK

以下が通ったコード


n, a, b = (int(i) for i in input().split())
 
x = b-a
if ((x % 2) == 0):
    print(x//2)
    exit()
else:
    print(min(a-1, n-b) + (x+1)//2)
    exit()

感想

計算精度の話大学の授業でやったなぁ。。。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?