c++bug小结(一)

昨天打codeforces,碰到两个bug,在此总结。

用一元二次方程求解公式的精度问题

1、在这里用一元二次方程求解公式之后,由于数据较大极有可能造成精度不高导致转化int类型之后与实际结果差1或着差2。
如公式x*x+x-c>=0,求出满足公式的最小整数x。
这里用一元二次方程求解,由于精度的问题,导致无法得到正确结果。此时将公式转化一下 x*x+x > =c,
假设x*x+x =c,
则 x < sqrt(x*x+x) < x+1
即有x < sqrt(c) < x+1。
所以求出sqrt(c)的上界i,并逐渐递减判断是否i*i+i>=c,是就继续递减,否则得出结果。

无法整除的乘除法运算不能调换

a/b*x 与a*x/b看似这两个步骤得出的结果一样,其实不然。
举个例子,a = 3,b=2, x = 2
式一得出结果 2,式二得出结果3
这也是在写codeforces的拓展欧几里德算法找了一两个小时找到的bug。。
如下:
错误写法:y-=a*x/b;

long long gcd(long long a, long b, long long &x, long long & y) {
    if (!b) {
        x = 1;
        y = 0;
        return a;
    }
    long long g = gcd (b, a%b, y, x);
    y -= a*x/b;
    return g;
}

正确写法:y-=a/b*x;

long long gcd(long long a, long b, long long &x, long long & y) {
    if (!b) {
        x = 1;
        y = 0;
        return a;
    }
    long long g = gcd (b, a%b, y, x);
    y -= a/b*x;
    return g;
}

关于对拓展欧几里德算法的推导,见我以前的文章:

拓展欧几里德算法推导

你可能感兴趣的:(c语言/c++学习)