問題概略
半径が等しくて互いに外接する 3 つの円が大きい円に内接している。
この図形がもつ 4 つのすき間を円で埋める操作を繰り返す。各ステップですべてのすき間にそれぞれ最大の円を置いていくと,3 ステップ後には図のようになる。
108 のすき間ができ,円で埋められていない面積の比率は 10 進 8 桁に四捨五入して 0.06790342 である。10 ステップ後に円で埋まっていない面積の比率を 10 進 8 桁に四捨五入して の形で答えよ。
解説の pdf も作りました。きれいなレイアウトで読みたい方はこちらをどうぞ。
パターンを見抜く
この問題で求めるのは比率だけなので,一番外側にある大円の半径を として一般性を失いません。
内部にある 3 つの小円の半径は です。
与えられた図を漫然と眺めるととりつく島もない感じですが,色ごとに見るとパターンがわかります。
「3 つの円から新しい円ができる」→「その円のまわりに新しい円が 3 つできる」の繰り返しです。
最初にある 4 つの円から作られる円の半径をまとめて であらわすと,求める比率は次の式で与えられます。
\begin{align*}
\texttt{ans}=\frac{\pi{r_0}^2-3\pi{r_1}^2-\sum \pi r^2 }{\pi{r_0}^2} &=1-3{r_1}^2-\sum r^2
\end{align*}
デカルトの円定理
新しくできる円の半径はデカルトの円定理で求められます。
これは「互いに接する 4 つの円の半径はある 2 次方程式をみたす」という定理です。
半径 の円の曲率を で定義します。
符号は他の円を内部に含むときマイナスで,含まないときはプラスです。
この問題の場合,一番外側にある大円だけマイナスで,残りの円はすべてプラスです。
曲率 , , , の円が互いに接するとき
が成立します。正の解を求めると
新しくできる円の半径は です。
計算に使う関係式
と , , の関係を であらわすと,次のようにして円が作られていきます。
- 曲率 , , の円から曲率 の円ができる
- 曲率 , , の円ができる
求める比はこれを 10 回繰り返したときの です。
dfs と対称性を使って計算しました。
上の操作を , , からはじめて 回繰り返したときの の和を で表します。
python と mathematicaで実装
python で解く
pythonによるコードがこちら。計算時間は 0.03 秒~0.04 秒でした。
import time, math def f(a, b, c, depth): if depth == 0: return 0 k = a + b + c + 2 * math.sqrt(a * b + b * c + c * a) return 1 / (k * k) + f(k, a, b, depth - 1) \ + f(k, b, c, depth - 1) + f(k, c, a, depth - 1) def solve(n): r0, r1 = 1, 2 * math.sqrt(3) - 3 k0, k1 = -1 / r0, 1 / r1 return 1 - 3 * r1 ** 2 - 3 * f(k0, k1, k1, n) - f(k1, k1, k1, n) if __name__ == '__main__': start = time.time() print('{:.8f}'.format(solve(10))) elapsed_time = time.time() - start print("elapsed_time: {0} [sec]".format(elapsed_time))
mathematicaで解く
mathematica は厳密解を求めようとするようで,何も考えずに計算させるとすごい時間がかかります。
円を作る操作が 8 回を超えたあたりで固まったように遅くなりました。
の値を N で囲んで,数値計算するように指定したら 0.5 秒くらいで答えが出ました。
r0 = 1; r1 = N[2 Sqrt@3 - 3, 9]; k0 = -1/r0; k1 = 1/r1; f[a_, b_, c_, 0] := 0; f[a_, b_, c_, n_] := Module[{k = a + b + c + 2*Sqrt[a*b + b*c + c*a]}, 1/k^2 + f[k, a, b, n - 1] + f[k, b, c, n - 1] + f[k, c, a, n - 1]]; n = 10; ans = N[1 - 3*r1^2 - 3*f[k0, k1, k1, n] - f[k1, k1, k1, n], 8]