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

#include <bits/stdc++.h>
using namespace std;

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define PI 3.141592653589793238
struct Point3D {
  double x, y, z;
  Point3D() {}
  Point3D(double x, double y, double z) : x(x), y(y), z(z) {}
  Point3D operator+(Point3D p) { return Point3D(x + p.x, y + p.y, z + p.z); }
  Point3D operator-(Point3D p) { return Point3D(x - p.x, y - p.y, z - p.z); }
  Point3D operator*(double k) { return Point3D(x * k, y * k, z * k); }
  Point3D operator/(double k) { return Point3D(x / k, y / k, z / k); }
};

typedef Point3D Vector3D;

struct Segment3D {
  Point3D p1, p2;
  Segment3D() {}
  Segment3D(Point3D p1, Point3D p2) : p1(p1), p2(p2) {}
};
typedef Segment3D Line3D;

struct Sphere {
  Point3D c;
  double r;
  Sphere() {}
  Sphere(Point3D c, double r) : c(c), r(r) {}
};

double norm(Vector3D a) { return a.x * a.x + a.y * a.y + a.z * a.z; }

double abs(Vector3D a) { return sqrt(norm(a)); }

double dot(Vector3D a, Vector3D b) { return a.x * b.x + a.y * b.y + a.z * b.z; }

Vector3D cross(Vector3D a, Vector3D b) {
  return Vector3D(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 getDistanceLP(Line3D l, Point3D p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

double getDistanceSP(Segment3D s, Point3D p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return abs(p - s.p2);
  return getDistanceLP(s, p);
}

bool intersectSC(Segment3D s, Sphere c) {
  double d = getDistanceSP(s, c.c);
  if (d > c.r)
    return 0;
  return !((abs(s.p1 - c.c) <= c.r) && (abs(s.p2 - c.c) <= c.r));
}

double calc(double b, Point3D a, Point3D e) {
  return b / (pow(a.x - e.x, 2) + pow(a.y - e.y, 2) + pow(a.z - e.z, 2));
}

int main() {
  int N, M, R;
  while (cin >> N >> M >> R, N) {
    vector<Sphere> s(N);
    for (int i = 0; i < N; i++) {
      cin >> s[i].c.x >> s[i].c.y >> s[i].c.z >> s[i].r;
    }
    vector<Point3D> p(M);
    vector<double> b(M);
    for (int i = 0; i < M; i++) {
      cin >> p[i].x >> p[i].y >> p[i].z >> b[i];
    }
    Point3D E;
    cin >> E.x >> E.y >> E.z;

    vector<int> ps[M];
    for (int i = 0; i < M; i++) {
      Segment3D seg = Segment3D(E, p[i]);
      for (int j = 0; j < N; j++) {
        if (intersectSC(seg, s[j])) {
          ps[i].emplace_back(j);
        }
      }
    }

    vector<double> sums(1 << M, 0);
    for (int i = 0; i < (1 << M); i++) {
      for (int j = 0; j < M; j++) {
        if (!(i & (1 << j)))
          continue;
        sums[i] += calc(b[j], p[j], E);
      }
    }

    double ans = 0;
    for (int i = 0; i < (1 << M); i++) {
      int cnt = 0;
      vector<int> used(N, 0);
      for (int j = 0; j < M; j++) {
        if (!(i & (1 << j)))
          continue;
        // if ( ps[j].size() > R ) break;
        for (int k : ps[j]) {
          if (used[k])
            continue;
          cnt++;
          used[k] = true;
        }
        if (cnt > R) {
          break;
        }
      }
      if (cnt <= R)
        ans = max(ans, sums[i]);
    }

    printf("%.12lf\\n", ans);
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define EPS (1e-9)

struct Point3D {
  double x, y, z;
  Point3D() {}
  Point3D(double x, double y, double z) : x(x), y(y), z(z) {}

  Point3D operator+(const Point3D &p) const {
    return Point3D(x + p.x, y + p.y, z + p.z);
  }

  Point3D operator-(const Point3D &p) const {
    return Point3D(x - p.x, y - p.y, z - p.z);
  }

  Point3D operator*(double k) const { return Point3D(x * k, y * k, z * k); }

  Point3D operator/(double k) const { return Point3D(x / k, y / k, z / k); }
};

typedef Point3D Vector;

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

double norm(const Point3D &p) { return dot(p, p); }

double abs(const Point3D &p) { return sqrt(norm(p)); }

double cross(const Point3D &a, const Point3D &b) {
  return abs(Point3D(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z,
                     a.x * b.y - a.y * b.x));
}

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

int ccw(const Point3D &p0, const Point3D &p1, const Point3D &p2) {
  Vector a = p1 - p0, b = p2 - p0;
  if (abs(cross(a, b)) > EPS)
    return +1;
  if (abs(cross(a, b)) < -EPS)
    return -1;
  if (dot(a, b) < -EPS)
    return +2;
  if (norm(a) < norm(b))
    return -2;
  return +0;
}

struct Segment {
  Point3D s, t;
  Segment() {}
  Segment(Point3D s, Point3D t) : s(s), t(t) {}
};

Point3D projection(const Segment &s, const Point3D &p) {
  Point3D b = s.t - s.s;
  double t = dot(p - s.s, b) / norm(b);
  return s.s + b * t;
}

double distanceSP(const Segment &s, const Point3D &p) {
  return abs(p - projection(s, p));
}

bool is_intersectSS(const Sphere &c, const Segment &l) {
  vector<Point3D> vec;
  double d = distanceSP(l, c.p);
  if (d < c.r) {
    Point3D p = projection(l, c.p);
    Point3D 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 (int i = 0; i < (int)vec.size(); i++) {
      if (ccw(l.s, l.t, vec[i]) == 0) {
        return true;
      }
    }
  }
  return false;
}

struct Light {
  Point3D p;
  double b;
  Light() {}
  Light(Point3D p, double b) : p(p), b(b) {}
};

double get_point(const Point3D &E, const Light &T) {
  return T.b / ((T.p.x - E.x) * (T.p.x - E.x) + (T.p.y - E.y) * (T.p.y - E.y) +
                (T.p.z - E.z) * (T.p.z - E.z));
}

void merge(set<int> &u, set<int> &v) {
  for (set<int>::iterator it = v.begin(); it != v.end(); ++it) {
    u.insert(*it);
  }
}

int main() {
  int N, M, R;
  while (cin >> N >> M >> R, N) {
    vector<Sphere> sphs(N);
    for (int i = 0; i < N; i++) {
      cin >> sphs[i].p.x >> sphs[i].p.y >> sphs[i].p.z >> sphs[i].r;
    }
    vector<Light> ligs(M);
    for (int i = 0; i < M; i++) {
      cin >> ligs[i].p.x >> ligs[i].p.y >> ligs[i].p.z >> ligs[i].b;
    }

    Point3D E;
    cin >> E.x >> E.y >> E.z;

    set<int> st[M];
    for (int i = 0; i < M; i++) {
      Segment s(E, ligs[i].p);
      for (int j = 0; j < N; j++) {
        if (is_intersectSS(sphs[j], s)) {
          st[i].insert(j);
        }
      }
    }

    double res = 0;
    for (int i = 0; i < (1 << M); i++) {
      set<int> used;
      double point = 0;
      for (int j = 0; j < M; j++) {
        if (!(i >> j & 1))
          continue;
        point += get_point(E, ligs[j]);
        merge(used, st[j]);
      }
      if (used.size() <= R) {
        res = max(res, point);
      }
    }
    printf("%.10f\\n", res);
  }
  return 0;
}