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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

const double g = 9.8;
const double eps = 1e-10;
const int maxn = 500;

int n, v, x, y;
int l[maxn], b[maxn], r[maxn], t[maxn];

double cal(double vy, double t) { return vy * t - g * t * t / 2; }

int cmp(double lb, double ub, double a) {
  return a < lb + eps ? -1 : a > ub - eps ? 1 : 0;
}

bool check(double qx, double qy) {
  double a = g * g / 4, B = g * qy - v * v, c = qx * qx + qy * qy;
  double d = B * B - 4 * a * c;
  if (d < 0 && d > -eps)
    d = 0;
  if (d < 0)
    return false;
  for (int D = -1; D <= 1; D += 2) {
    double t2 = (-B + D * sqrt(d)) / (2 * a);
    if (t2 <= 0)
      continue;
    double T = sqrt(t2);
    double vx = qx / T, vy = (qy + g * T * T / 2) / T;
    double yt = cal(vy, x / vx);
    if (yt < y - eps)
      continue;

    bool ok = true;
    for (int i = 0; i < n; i++) {
      if (l[i] >= x)
        continue;
      if (r[i] == x && y <= t[i] && b[i] <= yt)
        ok = false;
      int yl = cmp(1.0 * b[i], 1.0 * t[i], 1.0 * cal(vy, l[i] / vx));
      int yr = cmp(1.0 * b[i], 1.0 * t[i], 1.0 * cal(vy, r[i] / vx));
      int xh = cmp(1.0 * l[i], 1.0 * r[i], 1.0 * vx * (vy / g));
      int yh = cmp(1.0 * b[i], 1.0 * t[i], 1.0 * cal(vy, vy / g));
      if (xh == 0 && yh >= 0 && yl < 0)
        ok = false;
      if (yl * yr <= 0)
        ok = false;
    }
    if (ok)
      return true;
  }
  return false;
}

void solve() {
  for (int i = 0; i < n; i++) {
    r[i] = min(r[i], x);
  }
  bool ok = check(x, y);
  for (int i = 0; i < n; i++) {
    ok |= check(l[i], t[i]);
    ok |= check(r[i], t[i]);
  }
  puts(ok ? "Yes" : "No");
}

int main() {
  while (~scanf("%d%d%d%d", &n, &v, &x, &y)) {
    for (int i = 0; i < n; i++) {
      scanf("%d%d%d%d", &l[i], &b[i], &r[i], &t[i]);
    }
    solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

/*
 *   Copyright (C) 2014 All rights reserved.
 *
 *   filename: 2308.cpp
 *   author: doublehh
 *   e-mail: sserdoublehh@foxmail.com
 *   create time: 2014-10-01
 *   last modified: 2014-10-01 10:56:18
 */
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 55;
const double eps = 1e-8, inf = 1e10, g = 9.8;
int n;
double v, X, Y;
double x[maxn][2], y[maxn][2];
typedef pair<double, int> pdi;
typedef vector<pdi> V;
V Vec;
double MaxAc;

int dcmp(double x) { return (x > -eps) - (x < eps); }

void init() {
  for (int i = 0; i < n; i++)
    scanf("%lf%lf%lf%lf", &x[i][0], &y[i][0], &x[i][1], &y[i][1]);
}

void cal(double a, double b, double c, V &vec) {
  double delta = b * b - 4 * a * c;
  if (dcmp(delta) <= 0) {
    if (dcmp(a) > 0) {
      vec.push_back(make_pair(-inf, 1));
      vec.push_back(make_pair(inf, -1));
    }
    return;
  }

  delta = sqrt(delta);
  double t1 = (-b - delta) / (2 * a), t2 = (-b + delta) / (2 * a);
  if (dcmp(a) > 0) {
    while (t1 < -inf)
      ;
    while (t2 > inf)
      ;
    vec.push_back(make_pair(-inf, 1));
    vec.push_back(make_pair(t1, -1));
    vec.push_back(make_pair(t2, 1));
    vec.push_back(make_pair(inf, -1));
  } else {
    vec.push_back(make_pair(t1, 1));
    vec.push_back(make_pair(t2, -1));
  }
}

void add(double x1, double y1, double x2, double y2, int sign) {
  double a1 = -g * x1 * x1 / (2 * v * v), b1 = x1,
         c1 = -g * x1 * x1 / (2 * v * v) - y1;
  double a2 = -g * x2 * x2 / (2 * v * v), b2 = x2,
         c2 = -g * x2 * x2 / (2 * v * v) - y2;

  if (sign)
    a1 = -a1, a2 = -a2, b1 = -b1, b2 = -b2, c1 = -c1, c2 = -c2;

  V vec;
  cal(a1, b1, c1, vec);
  cal(a2, b2, c2, vec);
  sort(vec.begin(), vec.end());

  int tmp = 0;
  for (int i = 0; i + 1 < vec.size(); i++) {
    tmp += vec[i].second;
    if (tmp == 2) {
      double t = vec[i].first;
      Vec.push_back(make_pair(vec[i].first, 1));
      Vec.push_back(make_pair(vec[i + 1].first, -1));
    }
  }
}

bool judge(double l, double r) {
  double a = -g * X * X / (2 * v * v), b = X, c = -g * X * X / (2 * v * v);
  double fl = a * l * l + b * l + c, fr = a * r * r + b * r + c;
  double t = -b / (2 * a);
  double Min = min(fl, fr);
  double Max = max(fl, fr);
  if (dcmp(t - l) >= 0 && dcmp(t - r) <= 0)
    Max = a * t * t + b * t + c;

  return dcmp(Y - Min) >= 0 && dcmp(Y - Max) <= 0 ||
         dcmp(MaxAc - Min) >= 0 && dcmp(MaxAc - Max) <= 0;
}

bool solve() {
  if (!dcmp(v))
    return false;

  Vec.clear();
  MaxAc = inf;
  for (int i = 0; i < n; i++) {
    if (dcmp(x[i][0] - X) < 0) {
      x[i][1] = min(X, x[i][1]);
      add(x[i][0], y[i][0], x[i][1], y[i][0], 1);
      add(x[i][0], y[i][1], x[i][1], y[i][1], 0);
    }
    if (dcmp(X - x[i][0]) > 0 && dcmp(X - x[i][1]) < 0) {
      if (dcmp(y[i][0] - Y) >= 0)
        MaxAc = min(MaxAc, y[i][0]);
    }
  }

  Vec.push_back(make_pair(-inf, 0));
  Vec.push_back(make_pair(inf, 0));
  sort(Vec.begin(), Vec.end());

  int tmp = 0;
  for (int i = 0; i + 1 < Vec.size(); i++) {
    tmp += Vec[i].second;
    if (tmp == n) {
      for (;;)
        ;
      if (tmp == n && judge(Vec[i].first, Vec[i + 1].first))
        return true;
    }
  }
  return false;
}

int main() {
  while (~scanf("%d%lf%lf%lf", &n, &v, &X, &Y)) {
    init();
    puts(solve() ? "Yes" : "No");
  }
}