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

#include <bits/stdc++.h>

using namespace std;

// #define double long double

const double EPS = 1e-6;
#define eq(a, b) (fabs((a) - (b)) < EPS)

struct Point {
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double k) { return Point(x * k, y * k); }
  Point operator/(double k) { return Point(x / k, y / k); }
};
using Vector = Point;

double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
double norm(Vector a) { return dot(a, a); }
double abs(Vector a) { return sqrt(norm(a)); }

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
using Line = Segment;

const int CCW = 1;
const int CW = -1;
const int BACK = 2;
const int FRONT = -2;
const int ON = 0;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (cross(a, b) > EPS)
    return CCW;
  if (cross(a, b) < -EPS)
    return CW;
  if (dot(a, b) < -EPS)
    return BACK;
  if (norm(a) < norm(b))
    return FRONT;
  return ON;
}

bool isIntersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersectSS(Segment s1, Segment s2) {
  return isIntersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return abs(p - s.p2);
  return getDistanceLP(s, p);
}

double getDistanceSS(Segment s1, Segment s2) {
  if (isIntersectSS(s1, s2))
    return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
             min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

int main() {
  int N;
  cin >> N;
  vector<Segment> segs(N);
  for (int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs[i] = Segment(s, t);
  }
  if (N > 10000) {
    printf("%.12f\\n", 0.0);
    return 0;
  }

  double ans = LDBL_MAX / 2;
  for (int i = 0; i < N; ++i) {
    for (int j = i + 1; j < N; ++j) {
      // if(i == j) continue;
      ans = min(ans, getDistanceSS(segs[i], segs[j]));
    }
  }
  // printf("%.12Lf\\n", ans);
  printf("%.12f\\n", ans);

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define double long double

const double EPS = 1e-6;
#define eq(a, b) (fabs((a) - (b)) < EPS)

struct Point {
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double k) { return Point(x * k, y * k); }
  Point operator/(double k) { return Point(x / k, y / k); }
};
using Vector = Point;

double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
double norm(Vector a) { return dot(a, a); }
double abs(Vector a) { return sqrt(norm(a)); }

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
using Line = Segment;

const int CCW = 1;
const int CW = -1;
const int BACK = 2;
const int FRONT = -2;
const int ON = 0;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (cross(a, b) > EPS)
    return CCW;
  if (cross(a, b) < -EPS)
    return CW;
  if (dot(a, b) < -EPS)
    return BACK;
  if (norm(a) < norm(b))
    return FRONT;
  return ON;
}

bool isIntersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersectSS(Segment s1, Segment s2) {
  return isIntersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return abs(p - s.p2);
  return getDistanceLP(s, p);
}

double getDistanceSS(Segment s1, Segment s2) {
  if (isIntersectSS(s1, s2))
    return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
             min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

int main() {
  int N;
  cin >> N;
  vector<Segment> segs(N);
  for (int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs[i] = Segment(s, t);
  }
  if (N > 10000) {
    printf("%.12f\\n", 0.0);
    return 0;
  }

  double ans = LDBL_MAX / 2;
  for (int i = 0; i < N; ++i) {
    for (int j = i + 1; j < N; ++j) {
      // if(i == j) continue;
      ans = min(ans, getDistanceSS(segs[i], segs[j]));
    }
  }
  printf("%.12Lf\\n", ans);

  return 0;
}