分别使用二分法和牛顿法进行整数平方根的求解

下面是一道来自2022 CCF CSP-J1的一道阅读程序题。通过分析,我们理解如何用二分法和牛顿法来求整数的平方根。

原来的代码

先看试卷中的代码:

#include<iostream>
using namespace std;

// 假设int为32位有符号整数,输入的n是不超过47000的自然数,k是不超过int表示范围的自然数
int n, k;

int solve1() {
   
    int l = 0, r = n;
    while (l <= r) {
   
        int mid = (l + r) / 2;
        if (mid * mid <= n)
            l = mid + 1;
        else
            r = mid - 1;
    }
    return l - 1;
}

double solve2(double x) {
   
    if (x == 0)
        return x;
    for (int i = 0; i < k; i++)
        x = (x+n/x)/2;
    return x;
}

int main() {
   
    cin >> n >> k;
    double ans = solve2(solve1());
    cout << ans << ' ' << (ans * ans == n) << endl;
    return 0;
}

代码分析

以下是代码的分析:

  1. solve1() 函数

    • 这个函数使用二分查找法来找出 n 的整数平方根。
    • lr 是查找范围的左右边界。mid 是中间点,判断 mid * mid 是否小于等于 n 来决定调整查找范围。
    • l 小于 r 时,不断更新 lr,直到找到最大整数 l-1 使得 (l-1) * (l-1) <= n
  2. solve2(double x) 函数

    • 这个函数使用类似牛顿法的方法来近似平方根。
    • 初始值 xsolve1() 计算得到的整数平方根。然后进行 k 次迭代,更新 x(x + n / x) / 2 来逐步逼近真正的平方根。
    • 最终返回经过 k 次迭代后的近似值 x
  3. main() 函数

    • 读取输入的 nk
    • 使用 solve1() 计算 n 的整数平方根,然后用 solve2() 来近似这个平方根。
    • 输出近似的平方根值,并检查 ans * ans 是否等于 n 来验证计算结果的准确性。

可能的问题和改进:

  1. 二分查找中的整数溢出

    • 在二分查找中,如果 n 很大,mid * mid 可能会导致整数溢出。建议使用 long long 类型来避免溢出问题。
  2. solve2() 的初始猜测

    • solve2() 使用 solve1() 的结果作为初始值。虽然这是一个合理的起点,但对于牛顿法的收敛性,可能需要更精确的初始值或者更多的迭代。
  3. solve2() 的精度

    • k 的值决定了迭代次数,实际中可以根据需要调整迭代次数以获取所需精度。如果 k 值过小,可能无法获得足够精确的结果。
  4. 特殊情况处理

    • 确保处理了特殊情况,比如 n = 0。虽然你的代码在 solve2() 中处理了 x = 0,但在实际应用中,确保所有可能的边界条件都被考虑到是很重要的。

改进后的代码

以下是AI调整后的代码示例:

#include <iostream>
#include <cmath>  // 用于 std::fabs
using namespace std;

int n, k;

int solve1() {
   
    long long l 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值