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

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define each(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

typedef vector<double> P;
ostream &operator<<(ostream &os, const P &p) {
  return os << "(" << p[0] << ", " << p[1] << ", " << p[2] << ")";
}
inline P operator+(const P &a, const P &b) {
  P c(3);
  rep(i, 3) c[i] = a[i] + b[i];
  return c;
}
inline P operator-(const P &a, const P &b) {
  P c(3);
  rep(i, 3) c[i] = a[i] - b[i];
  return c;
}
inline P operator*(double s, P a) {
  rep(i, 3) a[i] *= s;
  return a;
}
inline double dot(const P &a, const P &b) {
  double res = 0;
  rep(i, 3) res += a[i] * b[i];
  return res;
}
inline P cross(const P &a, const P &b) {
  P c;
  c.pb(a[1] * b[2] - b[1] * a[2]);
  c.pb(b[0] * a[2] - a[0] * b[2]);
  c.pb(a[0] * b[1] - b[0] * a[1]);
  return c;
}
inline double norm(const P &a) { return dot(a, a); }
inline double abs(const P &a) { return sqrt(norm(a)); }

int n, m, r;
P s[2000], t[2000], o;
double sr[2000], tb[2000];
int flag[2000];

inline P projection(const P &a, const P &b, const P &p) {
  double t = dot(p - a, a - b) / norm(a - b);
  return a + t * (a - b);
}
inline bool intersectSP(const P &a, const P &b, const P &p) {
  if (abs(cross(a - b, p - b)) > EPS)
    return 0;
  double t = dot(p - b, a - b) / norm(a - b);
  return 0 <= t && t <= 1;
}
inline double distanceSP(const P &a, const P &b, const P &p) {
  const P r = projection(a, b, p);
  if (intersectSP(a, b, r))
    return abs(r - p);
  return min(abs(a - p), abs(b - p));
}
int calc(int bit) {
  int res = 0;
  rep(i, n) flag[i] = 0;

  rep(i, m) if (bit & 1 << i) {
    rep(j, n) if (!flag[j]) {
      double x = abs(s[j] - t[i]), y = abs(s[j]);
      double mn = distanceSP(o, t[i], s[j]);
      if ((mn < sr[j]) != (max(x, y) < sr[j])) {
        flag[j] = 1;
        res++;
      }
    }
  }
  return res;
}

int main() {
  o.resize(3);
  while (scanf("%d%d%d", &n, &m, &r), n) {
    rep(i, n) {
      vector<double> v(3);
      scanf("%lf%lf%lf%lf", &v[0], &v[1], &v[2], sr + i);
      s[i] = v;
    }
    rep(i, m) {
      vector<double> v(3);
      scanf("%lf%lf%lf%lf", &v[0], &v[1], &v[2], tb + i);
      t[i] = v;
    }
    P po(3);
    scanf("%lf%lf%lf", &po[0], &po[1], &po[2]);
    rep(i, n) s[i] = s[i] - po;
    rep(i, m) t[i] = t[i] - po;

    memset(flag, 0, sizeof(flag));
    rep(j, n) rep(i, m) {
      double x = abs(s[j] - t[i]), y = abs(s[j]);
      double mn = distanceSP(o, t[i], s[j]);
      if ((mn < sr[j]) != (max(x, y) < sr[j]))
        flag[j] |= 1 << i;
    }

    double ans = 0;
    rep(i, 1 << m) {
      int cnt = 0;
      rep(j, n) if (flag[j] & i) cnt++;
      if (cnt > r)
        continue;

      double sum = 0;
      rep(j, m) if (i & 1 << j) sum += tb[j] / norm(t[j]);
      ans = max(ans, sum);
    }
    printf("%.9f\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define each(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

typedef vector<double> P;
ostream &operator<<(ostream &os, const P &p) {
  return os << "(" << p[0] << ", " << p[1] << ", " << p[2] << ")";
}
inline P operator+(const P &a, const P &b) {
  P c(3);
  rep(i, 3) c[i] = a[i] + b[i];
  return c;
}
inline P operator-(const P &a, const P &b) {
  P c(3);
  rep(i, 3) c[i] = a[i] - b[i];
  return c;
}
inline P operator*(double s, P a) {
  rep(i, 3) a[i] *= s;
  return a;
}
inline double dot(const P &a, const P &b) {
  double res = 0;
  rep(i, 3) res += a[i] * b[i];
  return res;
}
inline P cross(const P &a, const P &b) {
  P c;
  c.pb(a[1] * b[2] - b[1] * a[2]);
  c.pb(b[0] * a[2] - a[0] * b[2]);
  c.pb(a[0] * b[1] - b[0] * a[1]);
  return c;
}
inline double norm(const P &a) { return dot(a, a); }
inline double abs(const P &a) { return sqrt(norm(a)); }

int n, m, r;
P s[2000], t[2000], o;
double sr[2000], tb[2000];
bool v[1 << 15], flag[2000];

inline P projection(const P &a, const P &b, const P &p) {
  double t = dot(p - a, a - b) / norm(a - b);
  return a + t * (a - b);
}
inline bool intersectSP(const P &a, const P &b, const P &p) {
  if (abs(cross(a - b, p - b)) > EPS)
    return 0;
  double t = dot(p - b, a - b) / norm(a - b);
  return 0 <= t && t <= 1;
}
inline double distanceSP(const P &a, const P &b, const P &p) {
  const P r = projection(a, b, p);
  if (intersectSP(a, b, r))
    return abs(r - p);
  return min(abs(a - p), abs(b - p));
}
int calc(int bit) {
  int res = 0;
  rep(i, n) flag[i] = 0;

  rep(i, m) if (bit & 1 << i) {
    rep(j, n) if (!flag[j]) {
      double x = abs(s[j] - t[i]), y = abs(s[j]);
      double mn = distanceSP(o, t[i], s[j]);
      if ((mn < sr[j]) != (max(x, y) < sr[j])) {
        flag[j] = 1;
        res++;
      }
    }
  }
  return res;
}

int main() {
  o.resize(3);
  while (scanf("%d%d%d", &n, &m, &r), n) {
    rep(i, n) {
      vector<double> v(3);
      scanf("%lf%lf%lf%lf", &v[0], &v[1], &v[2], sr + i);
      s[i] = v;
    }
    rep(i, m) {
      vector<double> v(3);
      scanf("%lf%lf%lf%lf", &v[0], &v[1], &v[2], tb + i);
      t[i] = v;
    }
    P po(3);
    scanf("%lf%lf%lf", &po[0], &po[1], &po[2]);
    rep(i, n) s[i] = s[i] - po;
    rep(i, m) t[i] = t[i] - po;

    double ans = 0;
    memset(v, 0, sizeof(v));
    rep(i, 1 << m) {
      for (int j = i; j; j = j - 1 & i)
        if (v[j]) {
          v[i] = 1;
          goto NEXT;
        }
      if (calc(i) > r)
        v[i] = 1;
      else {
        double sum = 0;
        rep(j, m) if (i & 1 << j) sum += tb[j] / norm(t[j]);
        ans = max(ans, sum);
      }
    NEXT:;
    }
    printf("%.9f\\n", ans);
  }
  return 0;
}