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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

const int inf = 1e9;
const double eps = 1e-9;
struct point {
  double x, y, z;
  point() : x(0), y(0), z(0) {}
  point(double x, double y, double z) : x(x), y(y), z(z) {}
  point operator+(const point &p) const {
    return point(x + p.x, y + p.y, z + p.z);
  }
  point operator-(const point &p) const {
    return point(x - p.x, y - p.y, z - p.z);
  }
  point operator*(const double &d) const { return point(x * d, y * d, z * d); }
  point operator/(const double &d) const { return point(x / d, y / d, z / d); }
};
struct sphere {
  point p;
  double r;
  sphere() {}
  sphere(point p, double r) : p(p), r(r) {}
};
struct line {
  point a, b;
  line() {}
  line(point a, point b) : a(a), b(b) {}
};

inline double norm(const point &a) { return a.x * a.x + a.y * a.y + a.z * a.z; }
inline double abs(const point &a) { return sqrt(norm(a)); }
inline double dot(const point &a, const point &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}
point proj(const line &l, const point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
bool intersect(const line &l, const sphere &s) {
  point a = l.a - s.p, b = l.b - s.p, c = proj(l, s.p) - s.p;
  if (abs(a) < s.r - eps && abs(b) < s.r - eps && abs(c) < s.r - eps)
    return 0; // contain
  if (abs(c) > s.r + eps)
    return 0; // far
  if (abs(a) < s.r - eps || abs(b) < s.r - eps)
    return 1; // intersect
  if (abs(a - c) + abs(b - c) < abs(a - b) + eps)
    return 1; // intersect
  return 0;
}

struct light {
  point p;
  double b;
};

sphere b[2000];
light l[15];
line lines[15];
point o;
vector<int> v[15];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M, R;
  while (cin >> N >> M >> R, N | M | R) {
    for (int i = 0; i < N; i++) {
      cin >> b[i].p.x >> b[i].p.y >> b[i].p.z >> b[i].r;
    }
    for (int i = 0; i < M; i++) {
      cin >> l[i].p.x >> l[i].p.y >> l[i].p.z >> l[i].b;
    }
    cin >> o.x >> o.y >> o.z;
    for (int i = 0; i < M; i++) {
      lines[i].a = l[i].p;
      lines[i].b = o;
    }

    for (int i = 0; i < M; i++) {
      v[i].clear();
      for (int j = 0; j < N; j++) {
        if (intersect(lines[i], b[j])) {
          v[i].push_back(j);
        }
      }
    }

    double ans = 0;
    for (int i = 0; i < 1 << M; i++) {
      vector<int> used(N);
      double sum = 0;
      int cnt = 0;
      for (int j = 0; j < M; j++) {
        if (i >> j & 1) {
          for (int x : v[j]) {
            if (!used[x]) {
              used[x] = true;
              cnt++;
            }
          }
          sum += l[j].b / norm(o - l[j].p);
        }
      }

      if (cnt <= R) {
        ans = max(ans, sum);
      }
    }

    cout << setprecision(15) << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

const int inf = 1e9;
const double eps = 1e-9;
struct point {
  double x, y, z;
  point() : x(0), y(0), z(0) {}
  point(double x, double y, double z) : x(x), y(y), z(z) {}
  point operator+(const point &p) const {
    return point(x + p.x, y + p.y, z + p.z);
  }
  point operator-(const point &p) const {
    return point(x - p.x, y - p.y, z - p.z);
  }
  point operator*(const double &d) const { return point(x * d, y * d, z * d); }
  point operator/(const double &d) const { return point(x / d, y / d, z / d); }
};
struct sphere {
  point p;
  double r;
  sphere() {}
  sphere(point p, double r) : p(p), r(r) {}
};
struct line {
  point a, b;
  line() {}
  line(point a, point b) : a(a), b(b) {}
};

inline double norm(const point &a) { return a.x * a.x + a.y * a.y + a.z * a.z; }
inline double abs(const point &a) { return sqrt(norm(a)); }
inline double dot(const point &a, const point &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}
point proj(const line &l, const point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
bool intersect(const line &l, const sphere &s) {
  point a = l.a - s.p, b = l.b - s.p, c = proj(l, s.p) - s.p;
  if (abs(a) < s.r - eps && abs(b) < s.r - eps && abs(c) < s.r - eps)
    return 0; // contain
  if (abs(c) > s.r + eps)
    return 0; // far
  if (abs(a) < s.r - eps || abs(b) < s.r - eps)
    return 1; // intersect
  if (abs(a - c) + abs(b - c) < abs(a - b) + eps)
    return 1; // intersect
  return 0;
}

struct light {
  point p;
  double b;
};

sphere b[2000];
light l[15];
line lines[15];
point o;
vector<int> v[15];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M, R;
  while (cin >> N >> M >> R, N | M | R) {
    for (int i = 0; i < N; i++) {
      cin >> b[i].p.x >> b[i].p.y >> b[i].p.z >> b[i].r;
    }
    for (int i = 0; i < M; i++) {
      cin >> l[i].p.x >> l[i].p.y >> l[i].p.z >> l[i].b;
    }
    cin >> o.x >> o.y >> o.z;
    for (int i = 0; i < M; i++) {
      lines[i].a = l[i].p;
      lines[i].b = o;
    }

    for (int i = 0; i < M; i++) {
      v[i].clear();
      for (int j = 0; j < N; j++) {
        if (intersect(lines[i], b[j])) {
          v[i].push_back(j);
        }
      }
    }

    double ans = 0;
    for (int i = 0; i < 1 << M; i++) {
      set<int> c;
      double sum = 0;
      for (int j = 0; j < M; j++) {
        if (i >> j & 1) {
          for (int x : v[j]) {
            c.insert(x);
          }
          sum += l[j].b / norm(o - l[j].p);
        }
      }
      if (c.size() <= R) {
        ans = max(ans, sum);
      }
    }

    cout << setprecision(15) << ans << endl;
  }
}