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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

struct point {
  double x, y, z;
  point() {}
  point(double x, double y, double z) : x(x), y(y), z(z) {}
  point operator-(const point &t) const {
    return point(x - t.x, y - t.y, z - t.z);
  }
  point operator*(double r) const { return point(x * r, y * r, z * r); }

  point operator+(const point &t) const {
    return point(x + t.x, y + t.y, z + t.z);
  }
};

inline double myabs2(const point &p) {
  return (p.x * p.x + p.y * p.y + p.z * p.z);
}

struct sphere {
  point center;
  double r;
  sphere();
  sphere(double x, double y, double z, double r) : center(x, y, z), r(r) {}
};

point from;
point to;
point gg;

inline double f(double p) {
  point v = to - from;
  point x = v * p + from;
  return myabs2(x - gg);
}

const double r5 = sqrt(5.);
const double eps = 1e-3;

double find_min(double a, double b, double f(double)) {
  const double r = 2. / (3. + r5);
  double c = a + r * (b - a), d = b - r * (b - a);
  double fc = f(c), fd = f(d);
  while (d - c > eps) {
    if (fc > fd) {
      a = c;
      c = d;
      d = b - r * (b - a);
      fc = fd;
      fd = f(d);
    } else {
      b = d;
      d = c;
      c = a + r * (b - a);
      fd = fc;
      fc = f(c);
    }
  }
  return fc;
}

double get_dist(const point &a, const point &la, const point &lb) {
  from = la;
  to = lb;
  gg = a;
  return find_min(0, 1, f);
}

int main() {
  while (true) {
    int N, M, R;

    scanf("%d%d%d", &N, &M, &R);
    // cin >> N >> M >> R;
    if (N == 0 && M == 0 && R == 0)
      break;

    vector<sphere> vs;
    for (int i = 0; i < N; ++i) {
      int x, y, z, r;
      // cin >> x >> y >> z >> r;
      scanf("%d%d%d%d", &x, &y, &z, &r);
      vs.push_back(sphere(x, y, z, r));
    }

    vector<point> vl;
    vector<double> vb;

    for (int i = 0; i < M; ++i) {
      int x, y, z, b;
      // cin >> x >> y >> z >> b;
      scanf("%d%d%d%d", &x, &y, &z, &b);
      vl.push_back(point(x, y, z));
      vb.push_back(b);
    }

    point E;
    // cin >> E.x >> E.y >> E.z;

    scanf("%lf%lf%lf", &E.x, &E.y, &E.z);
    bool touched[vl.size()][vs.size()];
    for (int i = 0; i < (int)vl.size(); ++i) {
      for (int j = 0; j < (int)vs.size(); ++j) {
        touched[i][j] = false;
        double rr = vs[j].r * vs[j].r;
        // cout << get_dist(vs[j].center, vl[i], E) << endl;
        if ((get_dist(vs[j].center, vl[i], E)) < rr &&
            (myabs2(vs[j].center - vl[i]) > rr ||
             myabs2(vs[j].center - E) > rr)) {
          touched[i][j] = true;
        }
      }
    }

    double res = 0;
    for (int bit = 0; bit < (1 << M); ++bit) {
      int S[N];
      for (int i = 0; i < N; ++i)
        S[i] = 0;

      double illum = 0;
      for (int k = 0; k < M; ++k) {
        if (bit & (1 << k)) {
          illum += vb[k] / myabs2(E - vl[k]);
          for (int i = 0; i < N; ++i) {
            if (touched[k][i]) {
              S[i] |= 1;
            }
          }
        }
      }

      int sz = 0;
      for (int i = 0; i < N; ++i) {
        sz += S[i];
      }
      if (sz > R)
        continue;
      else
        res = max(res, illum);
    }

    printf("%.8lf\\n", res);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

struct point {
  double x, y, z;
  point() {}
  point(double x, double y, double z) : x(x), y(y), z(z) {}
  point operator-(const point &t) const {
    return point(x - t.x, y - t.y, z - t.z);
  }
  point operator*(double r) const { return point(x * r, y * r, z * r); }

  point operator+(const point &t) const {
    return point(x + t.x, y + t.y, z + t.z);
  }
};

inline double myabs2(const point &p) {
  return (p.x * p.x + p.y * p.y + p.z * p.z);
}

struct sphere {
  point center;
  double r;
  sphere();
  sphere(double x, double y, double z, double r) : center(x, y, z), r(r) {}
};

point from;
point to;
point gg;

inline double f(double p) {
  point v = to - from;
  point x = v * p + from;
  return myabs2(x - gg);
}

const double r5 = sqrt(5.);
const double eps = 1e-5;

double find_min(double a, double b, double f(double)) {
  const double r = 2. / (3. + r5);
  double c = a + r * (b - a), d = b - r * (b - a);
  double fc = f(c), fd = f(d);
  while (d - c > eps) {
    if (fc > fd) {
      a = c;
      c = d;
      d = b - r * (b - a);
      fc = fd;
      fd = f(d);
    } else {
      b = d;
      d = c;
      c = a + r * (b - a);
      fd = fc;
      fc = f(c);
    }
  }
  return fc;
}

double get_dist(const point &a, const point &la, const point &lb) {
  from = la;
  to = lb;
  gg = a;
  return find_min(0, 1, f);
}

int main() {
  while (true) {
    int N, M, R;

    // scanf("%d%d%d", &N, &M, &R);
    cin >> N >> M >> R;
    if (N == 0 && M == 0 && R == 0)
      break;

    vector<sphere> vs;
    for (int i = 0; i < N; ++i) {
      int x, y, z, r;
      cin >> x >> y >> z >> r;
      // scanf("%d%d%d%d", &x, &y, &z, &r);
      vs.push_back(sphere(x, y, z, r));
    }

    vector<point> vl;
    vector<double> vb;

    for (int i = 0; i < M; ++i) {
      int x, y, z, b;
      cin >> x >> y >> z >> b;
      // scanf("%d%d%d%d", &x, &y, &z, &b);
      vl.push_back(point(x, y, z));
      vb.push_back(b);
    }

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

    // scanf("%lf%lf%lf", &E.x, &E.y, &E.z);
    bool touched[vl.size()][vs.size()];
    for (int i = 0; i < (int)vl.size(); ++i) {
      for (int j = 0; j < (int)vs.size(); ++j) {
        touched[i][j] = false;
        double rr = vs[j].r * vs[j].r;
        // cout << get_dist(vs[j].center, vl[i], E) << endl;
        if ((get_dist(vs[j].center, vl[i], E)) < rr &&
            (myabs2(vs[j].center - vl[i]) > rr ||
             myabs2(vs[j].center - E) > rr)) {
          touched[i][j] = true;
        }
      }
    }

    double res = 0;
    for (int bit = 0; bit < (1 << M); ++bit) {
      int S[N];
      for (int i = 0; i < N; ++i)
        S[i] = 0;

      double illum = 0;
      for (int k = 0; k < M; ++k) {
        if (bit & (1 << k)) {
          illum += vb[k] / myabs2(E - vl[k]);
          for (int i = 0; i < N; ++i) {
            if (touched[k][i]) {
              S[i] |= 1;
            }
          }
        }
      }

      int sz = 0;
      for (int i = 0; i < N; ++i) {
        sz += S[i];
      }
      if (sz > R)
        continue;
      else
        res = max(res, illum);
    }

    printf("%.8lf\\n", res);
  }
  return 0;
}