I have implemented this solution for finding a root of a cubic function
f(x) = ax3 + bx2 + cx + d
given a
, b
, c
, and d
, ensuring it's being monotonic.
After submitting the solution to an online judge without being shown the test cases, I am being faced by a time limit error. a
, b
, c
, and d
guarantee that the function is monotonic and we know it is being continuous. The code first finds the interval [A, B]
such that f(A) * f(B) < 0
; then the code moves to implement the bisection search.
What I want to know is if there is some possibility to minimize the time complexity of my code so it passes the online judge. The input is a
, b
, c
, d
, and the output should be the root with an error 0.000001
.
Code:
#include <iostream>
#include <algorithm>
//#include <cmath>
//#include <string>
using namespace std;
int f(double a, double b, double c, double d, double x) {
return x*(x*(a*x + b) + c) + d;
}
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
double a, b, c, d, A, B, x = 1, res;
cin >> a >> b >> c >> d;
//determinning the interval
double f_x = f(a, b, c, d, x);
if (a > 0) { // strictly increasing
if (f_x > 0) { B = 0;
while (f(a, b, c, d, x) >= 0) { x -= x; }
A = x; }
else { A = 0;
while (f(a, b, c, d, x) <= 0) { x += x; }
B = x; }
}
else { //strictly decreasing
if (f_x > 0) { A = 0;
while (f(a, b, c, d, x) >= 0) { x += x; }
B = x; }
else { B = 0;
while (f(a, b, c, d, x) <= 0) { x -= x; }
A = x; }
}
// Bisection Search
double l = A;
while ((B - A) >= 0.000001)
{
// Find middle point
l = (A + B) / 2;
// Check if middle point is root
if (f(a, b, c, d, l) == 0.0)
break;
// Decide the side to repeat the steps
else if (f(a, b, c, d, l)*f(a, b, c, d, A) < 0)
B = l;
else
A = l;
}
res = l;
cout.precision(6);
cout << fixed << " " << res;
return 0;
}