Acwing.790.数的三次方根

217 阅读1分钟

www.acwing.com/problem/con…

解法一

二分

具体对于二分的解释,详见Acwing.789.数的范围。本题需要注意的一点是,循环结束的条件只能是一个精度范围,无法定义一个确定的结束条件,一般是比所需精度高两个数量级。

#include <cstdio>
#include <cmath>

int main() {
    double n;
    scanf("%lf", &n);
    
    double l, r;
    if(n > 0) l = 0, r = n;
    else l = n, r = 0;
    
    while(fabs(l - r) > 1e-8) {
        double mid = l + ((r - l) / 2);
        if(mid * mid * mid > n) r = mid;
        else l = mid;
    }
    
    printf("%.6lf\n", l);
    return 0;
}

2021年2月18号, 今天又去做了一遍这道题, 发现居然过不了了。原因是样例增强了, -0.001这个用例过不了, 答案-0.1不在-0.001到0之间, 所以没有办法找到正确答案。这里更新一下答案, 顺便保留原答案, 以供大家参考。

#include <cstdio>
#include <cmath>

int main(void) {
    double n;
    scanf("%lf", &n);
    
    double l = -10000, r = 10000;
    
    while(fabs(l - r) > 1e-8) {
        double mid = l + ((r - l) / 2);
        if(mid * mid * mid >= n) r = mid;
        else
            l = mid;
    }
    
    printf("%.6lf\n", l);
    return 0;
}

解法二

牛顿法

具体对牛顿法的推导和解释,见牛顿法的博文。

这里直接给出公式:

x=xx3n3x2=2x3+n3x2x = x - \frac{x^3-n}{3x^2} = \frac{2x^3+n}{3x^2}
#include <cstdio>

double getAns(double n) {
    double t = n;
    for(int i = 0; i < 100; i++) {
        t = (2 * t * t * t + n) / (3 * t * t);
    }
    
    return t;
}

int main() {
    double n;
    scanf("%lf", &n);
    
    printf("%.6lf\n", getAns(n));
    return 0;
}