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

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

struct P {
  int x, y;
  P(int x_, int y_) {
    x = x_;
    y = y_;
  }
  P() {}
};
bool exist[5001][5001];
int x[3001], y[3001];

int main() {
  int n;
  while (cin >> n, n) {
    for (int i = 0; i < 5001; i++) {
      for (int j = 0; j < 5001; j++) {
        exist[i][j] = false;
      }
    }
    for (int i = 0; i < n; i++) {
      cin >> x[i] >> y[i];
      exist[y[i]][x[i]] = true;
    }
    int ans = 0;
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        P p1 = P(x[i], y[i]);
        P p2 = P(x[j], y[j]);
        int dx = abs(p1.x - p2.x);
        int dy = abs(p1.y - p2.y);
        P p3(p2.x - dy, p2.y + dx);
        P p4(p1.x - dy, p1.y + dx);
        if (p3.x < 0 || p3.x > 5000 || p3.y < 0 || p3.y > 5000)
          continue;
        if (p4.x < 0 || p4.x > 5000 || p4.y < 0 || p4.y > 5000)
          continue;
        if (exist[p3.y][p3.x] && exist[p4.y][p4.x]) {
          ans = max(ans, dx * dx + dy * dy);
        }
        p3 = P(p1.x + dy, p1.y - dx);
        p4 = P(p2.x + dy, p2.y - dx);
        if (p3.x < 0 || p3.x > 5000 || p3.y < 0 || p3.y > 5000)
          continue;
        if (p4.x < 0 || p4.x > 5000 || p4.y < 0 || p4.y > 5000)
          continue;
        if (exist[p3.y][p3.x] && exist[p4.y][p4.x]) {
          ans = max(ans, dx * dx + dy * dy);
        }
      }
    }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

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

// * XY座標
#define X real()
#define Y imag()

// * 点の表現
typedef complex<double> P;

// * 許容する誤差ε
const double EPS = 1e-8;
// * Infinity
const double INF = 1e12;
// * 円周率
const double PI = acos(-1.0);
// * Infinity 2
const P INF_P(INF, INF);

// * complex<double> の順序を定義する
namespace std {
bool operator<(const P &a, const P &b) {
  return (real(a) != real(b)) ? real(a) < real(b) : imag(a) < imag(b);
}
} // namespace std

// * 2乗する
double sq(double x) { return x * x; }

// * 2点間の距離
double dist(P p1, P p2) { return abs(p1 - p2); }

// * 2つのスカラーが等しいかどうか
bool equal(double a, double b) { return (fabs(a - b) < EPS); }
// * 2つのベクトルが等しいかどうか
bool eq_v(P a, P b) { return (equal(a.X, b.X) && equal(a.Y, b.Y)); }

// ベクトルaの単位ベクトルを求める
P unit(P a) { return a / abs(a); }

// ベクトルaの法線ベクトルを求める
vector<P> normal(P a) {
  vector<P> vp;
  vp.push_back(a * P(0, 1));
  vp.push_back(a * P(0, -1));
  return vp;
}

// ベクトル a の単位法線ベクトルを求める
vector<P> normal_unit(P a) {
  vector<P> vp;
  vp.push_back((a * P(0, 1)) / abs(a));
  vp.push_back((a * P(0, -1)) / abs(a));
  return vp;
}

// * 内積 (dot product) : a・b = |a||b|cosΘ
double dot(P a, P b) { return real(conj(a) * b); }

// * 外積 (cross product) : a×b = |a||b|sinΘ
double cross(P a, P b) { return imag(conj(a) * b); }

// 点 p1, p2 を正方形の対角線として, 正方形のもう2つの頂点 p3, p4 を返す.
// p3のほうが x座標 が小さい方.
pair<P, P> f(P p1, P p2) {
  if (p2 < p1)
    swap(p1, p2);
  // 中点
  P mid = P((p1.X + p2.X) / 2.0, (p1.Y + p2.Y) / 2.0);
  // 点 p1 と 中点 の距離
  double length = dist(p1, mid);
  // 点 p3, p4 の計算
  vector<P> vp = normal_unit(p2 - p1);
  P p3 = (vp[0] * length) + mid;
  P p4 = (vp[1] * length) + mid;
  return pair<P, P>(p3, p4);
}

bool check(double x) {
  double x_ = fabs(x - ((int)x + EPS));
  return (x_ <= EPS);
}

bool is_exist(map<pair<int, int>, bool> &exist, int x, int y) {
  return exist.count(pair<int, int>(x, y));
}

int main() {
  int n;
  while (cin >> n, n) {
    map<pair<int, int>, bool> exist;
    vector<P> v(n);

    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      exist[pair<int, int>(x, y)] = true;
      v[i] = P(x, y);
    }
    int ans = 0;
    for (int i = 0; i < v.size(); i++) {
      for (int j = i + 1; j < v.size(); j++) {
        // if( dist(v[i],v[j]) < sqrt(ans)*sqrt(2.0) ) continue;
        pair<P, P> pp = f(v[i], v[j]);
        double x1 = pp.first.X;
        double y1 = pp.first.Y;
        double x2 = pp.second.X;
        double y2 = pp.second.Y;

        if (is_exist(exist, x1, y1) && is_exist(exist, x2, y2)) {
          // cout << v[i] << P(x1,y1) << v[j] << P(x2,y2) << endl;
          double d = dist(v[i], pp.first);
          ans = max(ans, (int)(d * d + EPS));
        }
      }
    }
    cout << ans << endl;
  }
}