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

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double mEPS = 1e-10;
const double PI = acos(-1.0);

class Point {
public:
  double x, y, z;

  Point(double x = 0.0, double y = 0.0, double z = 0.0) : 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 a) { return Point(a * x, a * y, a * z); }
  Point operator/(double a) { return Point(x / a, y / a, z / a); }

  double abs() { return sqrt(norm()); }
  double norm() { return x * x + y * y + z * z; }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  // EPS??????????°??????????
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < mEPS && fabs(y - p.y) < mEPS && fabs(z - p.z) < mEPS;
  }
};

class Segment {
public:
  Point p1, p2;
};

class Circle {
public:
  Point c;
  double r;
};

typedef vector<Point> Polygon;
typedef Point Vector;
typedef Segment Line;

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

Vector cross(Vector a, Vector b) {
  Vector v;
  v.x = a.y * b.z - a.z * b.y;
  v.y = a.z * b.x - a.x * b.z;
  v.z = a.x * b.y - a.y * b.x;
  return v;
}

double getDistanceLP(Line l, Point p) {
  Vector dl = l.p2 - l.p1, dp = p - l.p1;
  double t = dot(dp, dl) / dl.norm();
  return (dp - dl * t).abs();
}

//??????s??¨???p????????¢
double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return (p - s.p1).abs();
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return (p - s.p2).abs();
  return getDistanceLP(s, p);
}

int N, M, R;
VI dep[20];

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

  while (cin >> N >> M >> R, N != 0 || M != 0 || R != 0) {
    vector<Circle> ss(N);
    vector<Point> ts(M);
    vector<double> br(M);
    REP(i, N) cin >> ss[i].c.x >> ss[i].c.y >> ss[i].c.z >> ss[i].r;
    REP(i, M) cin >> ts[i].x >> ts[i].y >> ts[i].z >> br[i];
    Point obj;
    cin >> obj.x >> obj.y >> obj.z;

    vector<Segment> segs(M);
    REP(i, M) segs[i].p1 = ts[i], segs[i].p2 = obj;

    REP(i, M) {
      dep[i].clear();
      REP(j, N) {
        if ((segs[i].p1 - ss[j].c).abs() <= ss[j].r &&
            (segs[i].p2 - ss[j].c).abs() <= ss[j].r)
          continue;
        else if (getDistanceSP(segs[i], ss[j].c) <= ss[j].r) {
          dep[i].PB(j);
        }
      }
    }

    double ans = 0.;
    REP(bit, 1 << M) {
      int sum = 0;
      vector<bool> use(N, false);
      REP(i, M)
      if (bit >> i & 1)
        for (int x : dep[i])
          use[x] = true;

      REP(i, N) if (use[i])++ sum;
      if (sum <= R) {
        double tmp = 0.;
        REP(i, M) {
          if (bit >> i & 1)
            tmp += br[i] / (segs[i].p1 - segs[i].p2).norm();
        }
        ans = max(ans, tmp);
      }
    }
    cout << fixed << setprecision(9) << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double mEPS = 1e-10;
const double PI = acos(-1.0);

class Point {
public:
  double x, y, z;

  Point(double x = 0.0, double y = 0.0, double z = 0.0) : 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 a) { return Point(a * x, a * y, a * z); }
  Point operator/(double a) { return Point(x / a, y / a, z / a); }

  double abs() { return sqrt(norm()); }
  double norm() { return x * x + y * y + z * z; }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  // EPS??????????°??????????
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < mEPS && fabs(y - p.y) < mEPS && fabs(z - p.z) < mEPS;
  }
};

class Segment {
public:
  Point p1, p2;
};

class Circle {
public:
  Point c;
  double r;
};

typedef vector<Point> Polygon;
typedef Point Vector;
typedef Segment Line;

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

Vector cross(Vector a, Vector b) {
  Vector v;
  v.x = a.y * b.z - a.z * b.y;
  v.y = a.z * b.x - a.x * b.z;
  v.z = a.x * b.y - a.y * b.x;
  return v;
}

double getDistanceLP(Line l, Point p) {
  Vector dl = l.p2 - l.p1, dp = p - l.p1;
  double t = dot(dp, dl) / dl.norm();
  return (dp - dl * t).abs();
}

//??????s??¨???p????????¢
double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return (p - s.p1).abs();
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return (p - s.p2).abs();
  return getDistanceLP(s, p);
}

int N, M, R;
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while (cin >> N >> M >> R, N != 0 || M != 0 || R != 0) {
    vector<Circle> ss(N);
    vector<Point> ts(M);
    vector<double> br(M);
    REP(i, N) cin >> ss[i].c.x >> ss[i].c.y >> ss[i].c.z >> ss[i].r;
    REP(i, M) cin >> ts[i].x >> ts[i].y >> ts[i].z >> br[i];
    Point obj;
    cin >> obj.x >> obj.y >> obj.z;

    vector<Segment> segs(M);
    REP(i, M) segs[i].p1 = ts[i], segs[i].p2 = obj;

    bool dep[20][2010];
    REP(i, M) {
      REP(j, N) {
        if ((segs[i].p1 - ss[j].c).abs() <= ss[j].r &&
            (segs[i].p2 - ss[j].c).abs() <= ss[j].r)
          dep[i][j] = false;
        else if (getDistanceSP(segs[i], ss[j].c) <= ss[j].r) {
          dep[i][j] = true;
        } else
          dep[i][j] = false;
      }
    }

    double ans = 0.;
    REP(bit, 1 << M) {
      int sum = 0;
      vector<bool> use(N, false);
      REP(i, M)
      if (bit >> i & 1)
        REP(j, N) use[j] = use[j] || dep[i][j];

      REP(i, N) if (use[i])++ sum;
      if (sum <= R) {
        double tmp = 0.;
        REP(i, M) {
          if (bit >> i & 1)
            tmp += br[i] / (segs[i].p1 - segs[i].p2).norm();
        }
        ans = max(ans, tmp);
      }
    }
    cout << fixed << setprecision(9) << ans << endl;
  }

  return 0;
}