1183:反正切函数的应用

描述

反正切函数可展开成无穷级数,有如下公式:

使用反正切函数计算PI是一种常用的方法。例如,最简单的计算PI的方法:

PI=4arctan(1)=4(1-1/3+1/5-1/7+1/9-1/11+...) 公式(2)

然而,这种方法的效率很低,但我们可以根据角度和的正切函数公式:

tan(a+b)=[tan(a)+tan(b)]/[1-tan(a)*tan(b)] 公式(3)

通过简单的变换得到:

arctan(p)+arctan(q)=arctan[(p+q)/(1-pq)] 公式(4)

利用这个公式,令p=1/2,q=1/3,则(p+q)/(1-pq)=1,有

arctan(1/2)+arctan(1/3)=arctan[(1/2+1/3)/(1-1/2*1/3)]=arctan(1)

使用1/2和1/3的反正切来计算arctan(1),速度就快多了。
我们将公式(4)写成如下形式

arctan(1/a)=arctan(1/b)+arctan(1/c)

其中a,b和c均为正整数。

我们的问题是:对于每一个给定的a(1 <= a <= 60000),求b+c的值。我们保证对于任意的a都存在整数解。如果有多个解,要求你给出b+c最小的解。

输入

输入文件中只有一个正整数a,其中 1 <= a <= 60000。

输出

输出文件中只有一个整数,为 b+c 的值。

样例输入
1
样例输出
5
来源
Noi 01


分析

一道数学题呵

反正切函数是什么玩意?后面看看大佬的讲解才看懂。

(转载自博主雪彦x的atan2反正切,原文链接:atan2反正切-CSDN博客

1. tan(θ)
作用:根据一个角的弧度值,求该角的正切值;


实例:

1.tan(θ) = y/x
2. atan2(y, x)
功能: 求 y/x 的反正切值(即 θ)。并且atan2() 是 atan() 的增强版,能够确定角度所在的象限。(其实无需看太多文字,无非就是求反正切。和atan相同功能,但atan传参是斜率k即y/x(需要考虑x为0的情况),返回值是-90°~90°,但是atan2(y, x)返回值是-180°~180°角度更广)

注意:
反正切函数 atan2() 和正切函数 tan() 的功能恰好相反:tan() 是已知一个角的弧度值,求该角的正切值;而 atan2() 是已知一个角的正切值(也就是 y/x),求该角的弧度值。

两个point之间的 y / x返回值:

在第一象限,0 < θ < π/2
在第二象限,π/2 < θ ≤ π
在第三象限,-π < θ < -π/2
在第四象限,-π/2 < θ < 0
当 (x, y) 在象限的边界(也就是坐标轴)上时:

当 y 是 0,且 x 为非负值(x轴正方向),θ = 0
当 y 是 0,且 x 是负值(x轴反方向),θ = π
当 y 是正值,且 x 是 0,θ = π/2
当 y 是负值,且 x 是 0,θ = -π/2
实例:

point p1;
point p2;
double theta = atan2((p2.y- p1.y), (p2.x- p1.x));
//theta表示两个点之间的弧度

其实还蛮简单的

总体来说,

问题转化成求:mn=x,使得 m+n 最小,其中 x= (a*a+1)

有基本不等式 a+b>=2*sqrt(ab),所以尽量找靠近 sqrt(a*a+1) 的约数即可


代码

需要注意变量类型,不用long long类型计算数据会溢出。

代码出乎意料地短

#include <stdio.h>

int main(void)
{
    long long a, m;
    scanf("%lld", &a);
    for(m = a; ; m--)
        if(!((a * a + 1) % m))
            break;
    printf("%lld\n", 2 * a + m + (a * a + 1) / m);

    return 0;
}

给个赞和关注吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值