Problem p01425 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-7)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define pow2(a) ((a) * (a))

using namespace std;

const int MAX_N = 70;
const double g = 9.8;
int N;
double v0, X, Y;
double L[MAX_N], B[MAX_N], R[MAX_N], T[MAX_N];

bool LT(double a, double b) { return !equals(a, b) && a < b; }
bool LTE(double a, double b) { return equals(a, b) || a < b; }
bool GT(double a, double b) { return !equals(a, b) && a > b; }
bool GTE(double a, double b) { return equals(a, b) || a > b; }

inline double getY(double vy, double t) { return vy * t - (g * pow2(t)) / 2.0; }

int getLayer(double lb, double ub, double h) {
  return (LTE(h, lb) ? -1 : (GTE(h, ub) ? 1 : 0));
}

bool exec(double x, double y) {
  double a = pow2(g), b = 4 * (g * y - pow2(v0)), c = 4 * (pow2(x) + pow2(y));
  double D = b * b - 4 * a * c;
  vector<double> ts;
  if (LT(D, 0.0))
    return false;
  if (equals(a, 0.0)) {
    if (equals(b, 0.0))
      return false;
    if (LT(-c / b, 0.0))
      return false;
    ts.push_back(sqrt(-c / b));
  } else {
    if (equals(D, 0.0))
      D = 0;
    double tmp_t = (-b - sqrt(D)) / (2 * a);
    // cout << sqrt(tmp_t) << " ?+ ";
    if (GTE(tmp_t, 0.0))
      ts.push_back(sqrt(tmp_t));
    tmp_t = (-b + sqrt(D)) / (2 * a);
    // cout << sqrt(tmp_t) << endl;
    if (GTE(tmp_t, 0.0))
      ts.push_back(sqrt(tmp_t));
  }

  rep(i, ts.size()) {
    // cout << "ts[ " << i << "] = " << ts[i] << endl;
    double vx = x / ts[i], vy = y / ts[i] + (g * ts[i]) / 2.0;
    // cout << vx << " " << vy << endl;
    bool failed = false;
    for (int j = 0; !failed && j < N; j++) {
      if (GT(L[j], X))
        continue;

      double pig_t = X / vx;
      double pig_y = getY(vy, pig_t);
      // cout << vx << "," << vy << " -> " << pig_y << endl;
      if (LT(pig_y, Y)) {
        failed = true;
        break;
      }

      double rect_L_t = L[j] / vx;
      double rect_L_y = getY(vy, rect_L_t);
      int layer_L = getLayer(B[j], T[j], rect_L_y);

      double rect_R_t = R[j] / vx;
      double rect_R_y = getY(vy, rect_R_t);
      int layer_R = getLayer(B[j], T[j], rect_R_y);
      // cout << "getY = " <<vy << " " << R[j] << endl;
      if (layer_L * layer_R <= 0)
        failed = true;

      double top_t = vy / g;
      double top_x = vx * top_t;
      int layer_top_x = getLayer(L[j], R[j], top_x);

      double top_y = getY(vy, top_t);
      int layer_top_y = getLayer(B[j], T[j], top_y);

      // cout << rect_L_y << " ! " << rect_R_y << " ! " << top_x << " ! " <<
      // top_y << endl; cout << layer_L << "," << layer_R << "," << layer_top_x
      // << "," << layer_top_y << endl;

      // if( layer_top_x == 0 && layer_top_y >= 1 ) failed = true;
      if (layer_top_x == 0 && layer_top_y >= 0 && layer_L < 0)
        failed = true;
      // cout << "rect_L_y = " << rect_L_y << endl;
    }
    if (!failed) {
      // cout << "ok!! " << ts[i] << endl;
      return true;
    }
  }

  return false;
}

inline void compute() {
  bool success = false;
  rep(i, N) R[i] = min(R[i], X);
  for (int i = 0; !success && (i <= N); i++) {
    success |= exec(L[i], T[i]);
    // cout << endl << " success " << success << endl << endl;
    success |= exec(R[i], T[i]);
    // cout << endl << " success " << success << endl << endl;
  }
  cout << (success ? "Yes" : "No") << endl;
}

int main() {

  cin >> N >> v0 >> X >> Y;
  rep(i, N) cin >> L[i] >> B[i] >> R[i] >> T[i];
  L[N] = R[N] = X, B[N] = T[N] = Y;
  compute();
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-7)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define pow2(a) ((a) * (a))

using namespace std;

const int MAX_N = 70;
const double g = 9.8;
int N;
int v0, X, Y;
int L[MAX_N], B[MAX_N], R[MAX_N], T[MAX_N];

bool LT(double a, double b) { return !equals(a, b) && a < b; }
bool LTE(double a, double b) { return equals(a, b) || a < b; }
bool GT(double a, double b) { return !equals(a, b) && a > b; }
bool GTE(double a, double b) { return equals(a, b) || a > b; }

inline double getY(double vy, double t) { return vy * t - (g * pow2(t)) / 2.0; }

int getLayer(double lb, double ub, double h) {
  return (LT(h, lb) ? -1 : (GT(h, ub) ? 1 : 0));
}

bool exec(double x, double y) {
  double a = pow2(g), b = 4 * (g * y - pow2(v0)), c = 4 * (pow2(x) + pow2(y));
  double D = b * b - 4 * a * c;
  vector<double> ts;
  if (LT(D, 0.0))
    return false;
  if (equals(a, 0.0)) {
    if (equals(b, 0.0))
      return false;
    if (LT(-c / b, 0.0))
      return false;
    ts.push_back(sqrt(-c / b));
  } else {
    if (equals(D, 0.0))
      D = 0;
    double tmp_t = (-b - sqrt(D)) / (2 * a);
    // cout << sqrt(tmp_t) << " ?+ ";
    if (GTE(tmp_t, 0.0))
      ts.push_back(sqrt(tmp_t));
    tmp_t = (-b + sqrt(D)) / (2 * a);
    // cout << sqrt(tmp_t) << endl;
    if (GTE(tmp_t, 0.0))
      ts.push_back(sqrt(tmp_t));
  }

  rep(i, ts.size()) {
    // cout << "ts[ " << i << "] = " << ts[i] << endl;
    double vx = x / ts[i], vy = y / ts[i] + (g * ts[i]) / 2.0;
    // cout << vx << " " << vy << endl;
    bool failed = false;
    for (int j = 0; !failed && j < N; j++) {
      if (GT(L[j], X))
        continue;

      double pig_t = X / vx;
      double pig_y = getY(vy, pig_t);
      // cout << vx << "," << vy << " -> " << pig_y << endl;
      if (LT(pig_y, Y)) {
        failed = true;
        break;
      }

      double rect_L_t = L[j] / vx;
      int rect_L_y = getY(vy, rect_L_t);
      int layer_L = getLayer(B[j], T[j], rect_L_y);

      double rect_R_t = R[j] / vx;
      int rect_R_y = getY(vy, rect_R_t);
      int layer_R = getLayer(B[j], T[j], rect_R_y);

      if (layer_L * layer_R <= 0)
        failed = true;

      double top_t = vy / g;
      double top_x = vx * top_t;
      int layer_top_x = getLayer(L[j], R[j], top_x);

      double top_y = getY(vy, top_t);
      int layer_top_y = getLayer(B[j], T[j], top_y);

      // cout << rect_L_y << " ! " << rect_R_y << " ! " << top_x << " ! " <<
      // top_y << endl; cout << layer_L << "," << layer_R << "," << layer_top_x
      // << "," << layer_top_y << endl;

      // if( layer_top_x == 0 && layer_top_y >= 1 ) failed = true;
      if (layer_top_x == 0 && layer_top_y >= 0 && layer_L < 0)
        failed = true;
      // cout << "rect_L_y = " << rect_L_y << endl;
    }
    if (!failed) {
      // cout << "ok!! " << ts[i] << endl;
      return true;
    }
  }

  return false;
}

inline void compute() {
  bool success = false;
  for (int i = 0; !success && (i <= N); i++) {
    success |= exec(L[i], T[i]);
    // cout << endl << " success " << success << endl << endl;
    success |= exec(R[i], T[i]);
    // cout << endl << " success " << success << endl << endl;
  }
  cout << (success ? "Yes" : "No") << endl;
}

int main() {
  scanf("%d %lf %lf %lf", &N, &v0, &X, &Y);
  rep(i, N) scanf("%lf %lf %lf %lf", L + i, B + i, R + i, T + i);
  L[N] = R[N] = X, B[N] = T[N] = Y;
  compute();
  return 0;
}