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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) (v).begin(), (v).end()
#define resz(v, ...) (v).clear(), (v).resize(__VA_ARGS__)
#define reps(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

typedef pair<int, int> Pi;
typedef tuple<int, int, int> Ti;
typedef vector<int> vint;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

#define EPS (1e-8)
#define eq(a, b) (fabs((a) - (b)) < EPS)
#define lt(a, b) ((a) - (b) < -EPS)
#define le(a, b) (eq(a, b) || lt(a, b))

double sq(double x) { return x * x; }

struct Point {
  double x, y, z;
  double b;
  Point() {}
  Point(double x, double y, double z) : x(x), y(y), z(z) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y, z + p.z); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y, z - p.z); }
  Point operator*(double k) { return Point(x * k, y * k, z * k); }
  Point operator/(double k) { return Point(x / k, y / k, z / k); }
  bool operator<(const Point &p) const {
    if (x != p.x)
      return x < p.x;
    if (y != p.y)
      return y < p.y;
    return z < p.z;
  }
  double light(Point p) {
    return b / (sq(x - p.x) + sq(y - p.y) + sq(z - p.z));
  }
};
using Vector = Point;

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

struct Segment {
  Point s, t;
  Segment() {}
  Segment(Point s, Point t) : s(s), t(t) {}
};
using Line = Segment;

Point project(Line l, Point p) {
  Point q = l.t - l.s;
  double t = dot(p - l.s, q) / norm(q);
  return l.s + q * t;
}
double distLP(Line l, Point p) { return abs(p - project(l, p)); }

struct Sphere {
  Point p;
  double r;
  Sphere() {}
  Sphere(Point p, double r) : p(p), r(r) {}
};

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (abs(cross(a, b)) > EPS)
    return COUNTER_CLOCKWISE;
  if (abs(cross(a, b)) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}
bool intersect(Sphere c, Segment l) {
  vector<Point> vec;
  double d = distLP(l, c.p);
  if (le(d, c.r)) {
    Point p = project(l, c.p);
    Point v = (l.t - l.s) / abs(l.t - l.s);
    d = sqrt(c.r * c.r - d * d);
    vec.push_back(p - v * d);
    vec.push_back(p + v * d);
    for (auto q : vec) {
      if (ccw(l.s, l.t, q) == ON_SEGMENT)
        return true;
    }
  }
  return false;
}

int N, M, R;
vector<Sphere> S;
vector<Point> T;
vector<int> del[16];
// set<int> st;
bool used[2020];
Point E;

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while (cin >> N >> M >> R, N || M || R) {
    resz(S, N);
    resz(T, M);
    rep(i, N) cin >> S[i].p.x >> S[i].p.y >> S[i].p.z >> S[i].r;
    rep(i, M) cin >> T[i].x >> T[i].y >> T[i].z >> T[i].b;
    cin >> E.x >> E.y >> E.z;
    rep(i, 16) del[i].clear();
    rep(i, M) {
      Segment l(T[i], E);
      rep(j, N) {
        if (intersect(S[j], l))
          del[i].push_back(j);
      }
    }
    double ans = 0;
    rep(bit, 1 << M) {
      // st.clear();
      int cnt = 0;
      memset(used, false, sizeof(used));
      rep(i, M) {
        if (!((bit >> i) & 1))
          continue;
        rep(j, del[i].size()) {
          if (used[del[i][j]])
            continue;
          used[del[i][j]] = true; // st.insert(del[i][j]);
          cnt++;
        }
      }
      if (cnt > R)
        continue;
      // if((int)st.size() > R) continue;
      double tmp = 0;
      rep(i, M) {
        if ((bit >> i) & 1)
          tmp += T[i].light(E);
      }
      chmax(ans, tmp);
    }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) (v).begin(), (v).end()
#define resz(v, ...) (v).clear(), (v).resize(__VA_ARGS__)
#define reps(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

typedef pair<int, int> Pi;
typedef tuple<int, int, int> Ti;
typedef vector<int> vint;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

#define EPS (1e-8)
#define eq(a, b) (fabs((a) - (b)) < EPS)
#define lt(a, b) ((a) - (b) < -EPS)
#define le(a, b) (eq(a, b) || lt(a, b))

double sq(double x) { return x * x; }

struct Point {
  double x, y, z;
  double b;
  Point() {}
  Point(double x, double y, double z) : x(x), y(y), z(z) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y, z + p.z); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y, z - p.z); }
  Point operator*(double k) { return Point(x * k, y * k, z * k); }
  Point operator/(double k) { return Point(x / k, y / k, z / k); }
  bool operator<(const Point &p) const {
    if (x != p.x)
      return x < p.x;
    if (y != p.y)
      return y < p.y;
    return z < p.z;
  }
  double light(Point p) {
    return b / (sq(x - p.x) + sq(y - p.y) + sq(z - p.z));
  }
};
using Vector = Point;

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

struct Segment {
  Point s, t;
  Segment() {}
  Segment(Point s, Point t) : s(s), t(t) {}
};
using Line = Segment;

Point project(Line l, Point p) {
  Point q = l.t - l.s;
  double t = dot(p - l.s, q) / norm(q);
  return l.s + q * t;
}
double distLP(Line l, Point p) { return abs(p - project(l, p)); }

struct Sphere {
  Point p;
  double r;
  Sphere() {}
  Sphere(Point p, double r) : p(p), r(r) {}
};

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (abs(cross(a, b)) > EPS)
    return COUNTER_CLOCKWISE;
  if (abs(cross(a, b)) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}
bool intersect(Sphere c, Segment l) {
  vector<Point> vec;
  double d = distLP(l, c.p);
  if (le(d, c.r)) {
    Point p = project(l, c.p);
    Point v = (l.t - l.s) / abs(l.t - l.s);
    d = sqrt(c.r * c.r - d * d);
    vec.push_back(p - v * d);
    vec.push_back(p + v * d);
    for (auto q : vec) {
      if (ccw(l.s, l.t, q) == ON_SEGMENT)
        return true;
    }
  }
  return false;
}

int N, M, R;
vector<Sphere> S;
vector<Point> T;
Point E;

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while (cin >> N >> M >> R, N || M || R) {
    resz(S, N);
    resz(T, M);
    rep(i, N) cin >> S[i].p.x >> S[i].p.y >> S[i].p.z >> S[i].r;
    rep(i, M) cin >> T[i].x >> T[i].y >> T[i].z >> T[i].b;
    cin >> E.x >> E.y >> E.z;
    vector<int> del[M];
    rep(i, M) {
      Segment l(T[i], E);
      rep(j, N) {
        if (intersect(S[j], l))
          del[i].push_back(j);
      }
    }
    double ans = 0;
    rep(bit, 1 << M) {
      set<int> st;
      rep(i, M) {
        if (!((bit >> i) & 1))
          continue;
        rep(j, del[i].size()) st.insert(del[i][j]);
      }
      if ((int)st.size() > R)
        continue;
      double tmp = 0;
      rep(i, M) {
        if ((bit >> i) & 1)
          tmp += T[i].light(E);
      }
      chmax(ans, tmp);
    }
    cout << ans << endl;
  }

  return 0;
}