圆——高精无理数的处理


• 在第一象限中依次画圆
• 第一个圆半径为 𝑅 且和两坐标轴相切
• 接下来每一个圆和前一个圆以及两个坐标轴相切
• 求第 𝑛 个圆的半径(保留整数部分末尾1000位)

• 𝑛 ≤ 10^18, 𝑅 ≤ 10^9

就是这样。

 

题解:

肯定要想通过递推公式处理一下通项公式。然后尝试快速幂

可以得到:$R_n=(3+2\sqrt{2})^n\times R$

无理数小数点怎么处理?保留整数但是要乘R,(<=1e9)所以要保留小数点后9位。

直接算的话,肯定要爆精度的。因为1e-10还是会影响到答案的,不能直接舍去。

问题点在于处理精度误差。

但是,我们可以奇技淫巧一下:

$N=(3+2\sqrt{2})^n+(3-2\sqrt{2})^n$

那么,这个N一定是整数,因为无理数项都会消去。

我们可以求一个数对:$(a,b)=(a+b\sqrt{2})$

在平方中只会出现$\sqrt{2}$

所以,这个(a,b)可以自定义乘法,通过矩阵乘法求解。

 

然后我们要计算$N-(3-2 \sqrt{2})^n$还要注意小数点

$t=(3-2\sqrt{2})^n$

即:$ans=N\times R - t\times R$

那么,如果用double,这里的t能保证9位数的精度吗?

t本身是小于1的,

乘上n次,几乎就是0了。

所以,在没来得及爆精度的情况下,t就几乎变成0了,这样,如果t*R几乎为0,N要下取整,所以,$ans=N-1$

所以,直接再暴力用double算一遍$t$,然后乘上R减去,下取整即可。

 

值得注意的技巧:

1.有序数对(a,b)的做法

2.$N=(3+2\sqrt{2})^n+(3-2\sqrt{2})^n$的转化,利用$(3-2\sqrt{2})<1$,从而使得要么变成0,要么在double可以承受的范围下。

 

posted @ 2018-10-06 21:23  *Miracle*  阅读(410)  评论(0编辑  收藏  举报