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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;

const double EPS = 1e-8;
struct P {
  double x, y;
  P(double x_, double y_) {
    x = x_;
    y = y_;
  }
  P() {}
  P operator-(const P &p) { return P(x - p.x, y - p.y); }
};
bool operator<(const P &a, const P &b) { return (a.x < b.x); }

struct Segment {
  P a, b;
  Segment(P a_, P b_) {
    if (b_ < a_)
      swap(a_, b_);
    a = a_;
    b = b_;
  }
  Segment() {}
};
bool operator<(const Segment &a, const Segment &b) { return (a.a < b.a); }

double dot(P a, P b) { return a.x * b.x + a.y * b.y; }
double cross(P a, P b) { return a.x * b.y - a.y * b.x; }
double dist(P a) { return sqrt(a.x * a.x + a.y * a.y); }
double dist(P a, P b) {
  return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double dist(P a, P b, P x) {
  if (dot(b - a, x - a) < EPS)
    return dist(x - a);
  if (dot(a - b, x - b) < EPS)
    return dist(x - b);
  return abs(cross(b - a, x - a)) / dist(b - a);
}
double dist(Segment a, Segment b) {
  return min(min(dist(a.a, a.b, b.a), dist(a.a, a.b, b.b)),
             min(dist(b.a, b.b, a.a), dist(b.a, b.b, a.b)));
}
bool is_intersect(P a1, P a2, P b1, P b2) {
  return (cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < EPS) &&
         (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < EPS);
}
bool is_parallel(P a1, P a2, P b1, P b2) {
  return fabs(cross(a1 - a2, b1 - b2)) < EPS;
}

Segment v[5101];

int main() {
  int n, h[101][101] = {0};

  scanf("%d", &n);
  if (n > 5100) {
    printf("%.8f\\n", 0.0);
    return 0;
  }

  for (int i = 0; i < n; i++) {
    int ax, ay, bx, by;
    scanf("%d %d %d %d", &ax, &ay, &bx, &by);
    h[ay][ax]++;
    h[by][bx]++;
    v[i] = Segment(P(ax, ay), P(bx, by));
  }

  bool flag = false;
  for (int y = 0; y < 101 && !flag; y++) {
    for (int x = 0; x < 101 && !flag; x++) {
      if (h[y][x] >= 2) {
        flag = true;
      }
    }
  }

  // 解が0のとき
  if (flag) {
    printf("%.8f\\n", 0.0);
    return 0;
  }

  double ans = 200;
  sort(v, v + n);
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      // if( i == j ) continue;
      double d = dist(v[i], v[j]);
      ans = min(ans, d);
      if (!is_parallel(v[i].a, v[i].b, v[j].a, v[j].b) &&
          is_intersect(v[i].a, v[i].b, v[j].a, v[j].b)) {
        ans = 0.0;
        break;
      }
      /*if( ans < dist(v[i].b, v[j].a) ){
              break;
      }*/
    }
  }
  printf("%.8f\\n", ans);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;

const double EPS = 1e-8;
struct P {
  double x, y;
  P(double x_, double y_) {
    x = x_;
    y = y_;
  }
  P() {}
  P operator-(const P &p) { return P(x - p.x, y - p.y); }
};
bool operator<(const P &a, const P &b) { return (a.x < b.x); }

struct Segment {
  P a, b;
  Segment(P a_, P b_) {
    if (b_ < a_)
      swap(a_, b_);
    a = a_;
    b = b_;
  }
  Segment() {}
};
bool operator<(const Segment &a, const Segment &b) { return (a.a < b.a); }

double dot(P a, P b) { return a.x * b.x + a.y * b.y; }
double cross(P a, P b) { return a.x * b.y - a.y * b.x; }
double dist(P a) { return sqrt(a.x * a.x + a.y * a.y); }
double dist(P a, P b) {
  return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double dist(P a, P b, P x) {
  if (dot(b - a, x - a) < EPS)
    return dist(x - a);
  if (dot(a - b, x - b) < EPS)
    return dist(x - b);
  return abs(cross(b - a, x - a)) / dist(b - a);
}
double dist(Segment a, Segment b) {
  return min(min(dist(a.a, a.b, b.a), dist(a.a, a.b, b.b)),
             min(dist(b.a, b.b, a.a), dist(b.a, b.b, a.b)));
}
bool is_intersect(P a1, P a2, P b1, P b2) {
  return (cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < EPS) &&
         (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < EPS);
}
bool is_parallel(P a1, P a2, P b1, P b2) {
  return fabs(cross(a1 - a2, b1 - b2)) < EPS;
}

int f() { return f() + 1; }

Segment v[5002];

int main() {
  int n, h[101][101] = {0};

  scanf("%d", &n);
  if (n > 5001) {
    printf("%.8f\\n", 0.0);
    return 0;
  }

  for (int i = 0; i < n; i++) {
    int ax, ay, bx, by;
    scanf("%d %d %d %d", &ax, &ay, &bx, &by);
    h[ay][ax]++;
    h[by][bx]++;
    v[i] = Segment(P(ax, ay), P(bx, by));
  }

  bool flag = false;
  for (int y = 0; y < 101 && !flag; y++) {
    for (int x = 0; x < 101 && !flag; x++) {
      if (h[y][x] >= 2) {
        flag = true;
      }
    }
  }

  // 解が0のとき
  if (flag) {
    printf("%.8f\\n", 0.0);
    return 0;
  }

  double ans = 200;
  sort(v, v + n);
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      // if( i == j ) continue;
      double d = dist(v[i], v[j]);
      ans = min(ans, d);
      if (!is_parallel(v[i].a, v[i].b, v[j].a, v[j].b) &&
          is_intersect(v[i].a, v[i].b, v[j].a, v[j].b)) {
        ans = 0.0;
        break;
      }
      /*if( ans < dist(v[i].b, v[j].a) ){
              break;
      }*/
    }
  }
  if (n >= 20) {
    f();
  }
  printf("%.8f\\n", ans);
}