[yukicoder] No.691 E869120 and Constructing Array 5

スポンサーリンク

概要

問題文 →
公式解説 →
自分の提出 →

好きな問題です。楽しかったです。

解説で書かれていた方法とは違っていたので、書きます。私は結構難しい問題だと思いました。解けたので、書きます。

解法

小数部分が 10n にある程度近いような小数 xn を適当な方法で作ります。以下のようにしました。

x1=26=5.0990195135927845,x2=59+152=20.00997375380656,x3=29+58=13.000937912998413,x4=201+283=31.00005072001855,x5=457+763=49.000012960298214,x6=79+478+495=53.00000098767802,x7=385+444+454=62.00000012871658,x8=200+77+130+59=42.00000000998306,x9=454+21+212+308=58.00000000096364,x10=83+71+131+123+59+68=56.0000000000936.

数列の構成

実数 x の小数部分を、{x} と書くことにします。

実数 P が与えられたとします。n1={P}{x1} とすると、P1=Pn1x1 に対して {P1}<{x1} が成り立ちます。n2={P1}{x2} とすると、P2=P1n2x2 に対して {P2}<{x2} が成り立ちます。

以下、同様にして、{Pnixi}<x10<1010 となる {ni} をとることができます。

nixi は、ルートの和で書けることに注意しましょう。例えば n2x2=59n22+152n22 となります。これらを合わせると、29 個のルートの和を P から引くことで、P の小数部分を 1010 未満にできました。

ni<{xi1}{xi} で、xi はおおよそ 10 倍の等比数列にしてあるので、だいたい ni<10 です。xi は上を見ての通り、50 前後ですから、nixi はだいたい 5000 以下にはおさまります(ちゃんと計算していないです)。したがって、29 個のルートを引いた結果として、小数部分がとても小さな正の実数が残ります。最後にこれを非負整数(これも非負整数のルート)で近似すれば完成です。

xi の作り方

適当に探索しましょう。「1,,500 等で 3 つの和を全探索する」 みたいなことをやります。5003 個の数が作られるので、誤差 5003 くらいの数が見つかることを期待します。x7 まではこうやりました。さらに半分全列挙のテクニックを使って、4 つ組と 6 つ組も探すと、x8,x9,x10 も作れました。

コメント

xi の公比の目安 「10 倍」は適当な値です。「100 倍」くらいにすると、数列長の制約は簡単になる一方で 8000 以下におさめにくくなるというトレードオフがあります。

x4なんかを見ると分かるように、そんなに 10n にきちんと近い必要もないので、パラメータの取り方はとてもたくさんありそうです。ちょうど 30 項になったのは偶然でびっくりしました。使うパターンの工夫でまだ減らせると思います。

そもそも x2,x8,x10 にたまたま 3 回現れた 59 の寄与をまとめるだけで、28 項が実現できます。このように異なる xi に同じルートが使われているとオトクです。ルートの中に使う数 ri を決め打って、xk=niri という形で小数部分を調整すると、さらに項数の少ない構成ができるような気がします。

タイトルとURLをコピーしました