Problem p01337 (C++) — buggy submission, verdict: Runtime Error

// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;
const double EPS = 1e-8;

double sqrt_user(double x) {
  double lb = 0, ub = 10000;
  for (int i = 0; i < 200; i++) {
    double mid = (lb + ub) / 2.0;
    if (mid * mid < x)
      lb = mid;
    else
      ub = mid;
  }
  return lb;
}

int ans[3];
void put(double x) {
  if (abs(x) < EPS)
    ans[1]++;
  else if (x < -EPS)
    ans[2]++;
  else
    ans[0]++;
}

double f(double a, double b, double c, double d, double x) {
  return a * x * x * x + b * x * x + c * x + d;
}

double solve(double a, double b, double c, double d) {
  if (a == 0) {
    // printf("D = %.12f\\n", c*c - 4*b*d);
    if (c * c - 4 * b * d < -EPS)
      return 0;

    double vl = (-c + sqrt_user(c * c - 4 * b * d)) / (2 * b);
    double vr = (-c - sqrt_user(c * c - 4 * b * d)) / (2 * b);

    // printf("vl = %.12f, vr = %.12f\\n", vl, vr);
    put(vl);
    put(vr);

    return 0;
  } else {
    if (a < 0) {
      a = -a, b = -b, c = -c, d = -d;
    }

    double lb = -10000, ub = 10000;
    for (int i = 0; i < 300; i++) {
      double mid = (lb + ub) / 2.0;
      if (f(a, b, c, d, mid) > 0)
        ub = mid;
      else
        lb = mid;
    }

    put(lb);
    return lb;
  }
}

signed main() {
  int T;
  cin >> T;
  while (T--) {
    memset(ans, 0, sizeof(ans));
    int a, b, c, d;
    cin >> a >> b >> c >> d;

    double n = solve(a, b, c, d);
    // printf("n = %.12f\\n", n);
    solve(0, a, n * a + b, n * (n * a + b) + c);

    cout << ans[0] << " " << ans[2] << endl;
  }
  return 0;
}


Error: 0
0
0


Fixed submission:

// #error "tsurai"
#include <cmath>
#include <iostream>
#include <utility>
using namespace std;
const double EPS = 1e-7;

double f(double a, double b, double c, double d, double x) {
  return a * x * x * x + b * x * x + c * x + d;
}

pair<int, int> solve(double a, double b, double c, double d) {
  if (b * b - 3 * a * c < 0) {
    if (d > 0)
      return {0, 1};
    else
      return {1, 0};
  }
  double s = (-b - sqrt(b * b - 3 * a * c)) / 3 / a,
         t = (-b + sqrt(b * b - 3 * a * c)) / 3 / a;
  // cout << s << " " << t << endl;

  // if(abs(d) < EPS && abs(s) < EPS && abs(t) < EPS)
  //   return {0, 0};

  int p = 0, n = 0;
  cerr << f(a, b, c, d, s) << endl;
  if (t < -EPS) {
    if (f(a, b, c, d, 0) < 0)
      ++p;
    else
      ++n;
    if (f(a, b, c, d, s) * f(a, b, c, d, t) <= EPS)
      n += 2;
  } else if (s > EPS) {
    if (f(a, b, c, d, 0) < 0)
      ++p;
    else
      ++n;
    if (f(a, b, c, d, s) * f(a, b, c, d, t) <= EPS)
      p += 2;
  } else {
    if (f(a, b, c, d, s) >= -EPS && abs(s) > EPS)
      ++n;
    if (f(a, b, c, d, t) <= EPS && abs(t) > EPS)
      ++p;
    // cout << f(a,b,c,d,s)*f(a,b,c,d,t) << endl;
    // cout << f(a,b,c,d,t) << endl;
    if (f(a, b, c, d, s) * f(a, b, c, d, t) <= EPS) {
      if (f(a, b, c, d, 0) > EPS)
        ++p;
      else if (d < -EPS)
        ++n;
    }
  }
  return make_pair(p, n);
}

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    double a, b, c, d;
    cin >> a >> b >> c >> d;
    if (a < 0) {
      a = -a;
      b = -b;
      c = -c;
      d = -d;
    }
    pair<int, int> ans = solve(a, b, c, d);
    cout << ans.first << " " << ans.second << endl;
  }
  return 0;
}