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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;

struct Point {
  double x, y, z;
  Point(double x, double y, double z) : x(x), y(y), z(z) {}
  Point() {}
  Point &operator+=(const Point &a) {
    x += a.x;
    y += a.y;
    z += a.z;
    return *this;
  }
  Point &operator-=(const Point &a) {
    x -= a.x;
    y -= a.y;
    z -= a.z;
    return *this;
  }
  Point operator+(const Point &a) const {
    return Point(x + a.x, y + a.y, z + a.z);
  }
  Point operator-(const Point &a) const {
    return Point(x - a.x, y - a.y, z - a.z);
  }
  Point operator*(const double &a) const { return Point(a * x, a * y, a * z); }
};
struct Obj {
  Point p;
  double r;
  Obj(Point &p, double r) : p(p), r(r) {}
  Obj() {}
};

double dot(const Point &a, const Point &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}
double Length(const Point &a) { return sqrt(dot(a, a)); }

double distLP3(Point p, Point q, Point c) {
  p -= c;
  q -= c;
  Point v = q - p;
  double t = -dot(v, p) / dot(v, v);
  if (t < 0)
    return Length(p);
  if (t > 1)
    return Length(q);
  return Length(p + v * t);
}

int main() {
  while (1) {
    int n, m, r;
    cin >> n >> m >> r;
    if (n == 0 && m == 0 && r == 0)
      break;
    vector<Obj> s(n), t(m);
    for (int i = 0; i < n; i++) {
      cin >> s[i].p.x >> s[i].p.y >> s[i].p.z >> s[i].r;
    }
    for (int i = 0; i < m; i++) {
      cin >> t[i].p.x >> t[i].p.y >> t[i].p.z >> t[i].r;
    }
    Point e;
    cin >> e.x >> e.y >> e.z;

    vector<vector<int>> shut(m);
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (distLP3(e, t[i].p, s[j].p) + EPS < s[j].r &&
            (Length(e - s[j].p) > s[j].r + EPS ||
             Length(t[i].p - s[j].p) > s[j].r + EPS)) {
          shut[i].push_back(j);
        }
      }
    }
    vector<double> illum(m);
    for (int i = 0; i < m; i++) {
      illum[i] = t[i].r / dot(t[i].p - e, t[i].p - e);
    }

    double ans = 0;
    for (int i = 0; i < (1 << m); i++) {
      bitset<2000> bal;
      double total = 0;
      int count = 0;
      for (int j = 0; j < m; j++) {
        if ((1 << j & i) != 0) {
          for (int k = 0; k < (int)shut[j].size(); k++) {
            if (bal[shut[j][k]] == 0) {
              bal[shut[j][k]] = 1;
              count++;
            }
          }
          total += illum[j];
        }
        if (count > r)
          break;
      }
      if (count <= r) {
        ans = max(ans, total);
      }
    }
    cout << fixed;
    cout << setprecision(10);
    cout << ans << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;

struct Point {
  double x, y, z;
  Point(double x, double y, double z) : x(x), y(y), z(z) {}
  Point() {}
  Point &operator+=(const Point &a) {
    x += a.x;
    y += a.y;
    z += a.z;
    return *this;
  }
  Point &operator-=(const Point &a) {
    x -= a.x;
    y -= a.y;
    z -= a.z;
    return *this;
  }
  Point operator+(const Point &a) const {
    return Point(x + a.x, y + a.y, z + a.z);
  }
  Point operator-(const Point &a) const {
    return Point(x - a.x, y - a.y, z - a.z);
  }
  Point operator*(const double &a) const { return Point(a * x, a * y, a * z); }
};
struct Obj {
  Point p;
  double r;
  Obj(Point &p, double r) : p(p), r(r) {}
  Obj() {}
};

double dot(const Point &a, const Point &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}
double Length(const Point &a) { return sqrt(dot(a, a)); }

double distLP3(Point p, Point q, Point c) {
  p -= c;
  q -= c;
  Point v = q - p;
  double t = -dot(v, p) / dot(v, v);
  if (t < 0)
    return Length(p);
  if (t > 1)
    return Length(q);
  return Length(p + v * t);
}

int main() {
  while (1) {
    int n, m, r;
    cin >> n >> m >> r;
    if (n == 0 && m == 0 && r == 0)
      break;
    vector<Obj> s(n), t(m);
    for (int i = 0; i < n; i++) {
      cin >> s[i].p.x >> s[i].p.y >> s[i].p.z >> s[i].r;
    }
    for (int i = 0; i < m; i++) {
      cin >> t[i].p.x >> t[i].p.y >> t[i].p.z >> t[i].r;
    }
    Point e;
    cin >> e.x >> e.y >> e.z;

    vector<vector<int>> shut(m);
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (distLP3(e, t[i].p, s[j].p) + EPS < s[j].r &&
            (Length(e - s[j].p) > s[j].r + EPS ||
             Length(t[i].p - s[j].p) > s[j].r + EPS)) {
          shut[i].push_back(j);
        }
      }
    }
    vector<double> illum(m);
    for (int i = 0; i < m; i++) {
      illum[i] = t[i].r / dot(t[i].p - e, t[i].p - e);
    }

    double ans = 0;
    for (int i = 0; i < (1 << m); i++) {
      set<int> bal;
      double total = 0;
      for (int j = 0; j < m; j++) {
        if ((1 << j & i) != 0) {
          bal.insert(shut[j].begin(), shut[j].end());
          total += illum[j];
        }
      }
      if ((int)bal.size() <= r) {
        ans = max(ans, total);
      }
    }
    cout << fixed;
    cout << setprecision(10);
    cout << ans << endl;
  }
  return 0;
}