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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))

struct pos {
  double x, y, z;
  double norm, norm2;
  pos tov(pos a) { return (a - (*this)); }
  void initnorm() {
    norm2 = x * x + y * y + z * z;
    norm = sqrt(norm2);
  }
  pos operator+(pos a) const {
    pos res = a;
    res.x += x;
    res.y += y;
    res.z += z;
    res.initnorm();
    return res;
  }
  pos operator-(pos a) const {
    pos res = (*this);
    res.x -= a.x;
    res.y -= a.y;
    res.z -= a.z;
    res.initnorm();
    return res;
  }
  double dot(pos a) { return x * a.x + y * a.y + z * a.z; }
  pos(double ix, double iy, double iz) {
    x = ix;
    y = iy;
    z = iz;
  }
  pos() {}
  string str() {
    char ns[50];
    sprintf(ns, "(%.1lf %.1lf %.1lf)", x, y, z);
    return string(ns);
  }
};

struct line {
  pos p, q;
  pos vec;
  string str() { return ("(" + p.str() + "-" + q.str() + ")"); }
  line(pos ip, pos iq) {
    p = ip;
    q = iq;
    vec = p.tov(q);
  }
  line() {}
  double dist(pos a) {
    if (p.tov(a).dot(p.tov(q)) < 0)
      return p.tov(a).norm;
    if (q.tov(a).dot(q.tov(p)) < 0)
      return q.tov(a).norm;
    if (p.tov(a).norm < 1e-9)
      return p.tov(a).norm;
    if (q.tov(a).norm < 1e-9)
      return q.tov(a).norm;

    pos pa = p.tov(a);
    double co =
        abs(acos(max(-1.0, min(1.0, pa.dot(vec) / vec.norm / pa.norm))));
    // printf("%lf\\n",pa.dot(vec));
    return pa.norm * sin(co);
  }
};

pos sc[2005];
double sr[2005];

pos tc[20];
double tr[20];
double ds[20];

int isc[25][2005];

int n, m, r;
int main(void) {
  for (;;) {
    scanf("%d%d%d", &n, &m, &r);
    if (n + m + r == 0)
      break;
    rep(i, n) {
      double x, y, z;
      scanf("%lf%lf%lf%lf", &x, &y, &z, &sr[i]);
      sc[i] = pos(x, y, z);
    }
    rep(i, m) {
      double x, y, z;
      scanf("%lf%lf%lf%lf", &x, &y, &z, &tr[i]);
      tc[i] = pos(x, y, z);
    }
    pos oc;
    {
      double x, y, z;
      scanf("%lf%lf%lf", &x, &y, &z);
      oc = pos(x, y, z);
    }
    memset(isc, 0, sizeof(isc));

    rep(i, m) {
      line a(oc, tc[i]);
      rep(j, n) {
        if (sc[j].tov(oc).norm < sr[j] && sc[j].tov(tc[i]).norm < sr[j])
          continue;
        if (a.dist(sc[j]) > sr[j])
          continue;
        isc[i][j] = 1;
      }
      ds[i] = tr[i] / a.vec.norm2;
    }
    /*
    rep(i,m){
            line a(oc,tc[i]);
            rep(j,n){
                    printf("%d %d %s %d %s %lf %lf\\n",
                            isc[i][j],
                            i,a.str().c_str(),
                            j,sc[j].str().c_str(),
                            a.dist(sc[j]),
                            sr[j]);
            }
    }*/

    double ans = 0;

    rep(i, 1 << m) {
      int cn = 0;
      rep(j, n) {
        bool b = false;
        rep(k, m) {
          if ((i & (1 << k)) == 0)
            continue;
          if (isc[k][j])
            b = true;
        }
        if (b)
          cn++;
      }
      if (cn > r)
        continue;
      double ns = 0;
      rep(j, m) {
        if ((i & (1 << j)) == 0)
          continue;
        ns += ds[j];
      }
      // printf("%d %d %lf\\n",i,cn,ns);

      ans = max(ans, ns);
    }
    printf("%f\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))

struct pos {
  double x, y, z;
  double norm, norm2;
  pos tov(pos a) { return (a - (*this)); }
  void initnorm() {
    norm2 = x * x + y * y + z * z;
    norm = sqrt(norm2);
  }
  pos operator+(pos a) const {
    pos res = a;
    res.x += x;
    res.y += y;
    res.z += z;
    res.initnorm();
    return res;
  }
  pos operator-(pos a) const {
    pos res = (*this);
    res.x -= a.x;
    res.y -= a.y;
    res.z -= a.z;
    res.initnorm();
    return res;
  }
  double dot(pos a) { return x * a.x + y * a.y + z * a.z; }
  pos(double ix, double iy, double iz) {
    x = ix;
    y = iy;
    z = iz;
  }
  pos() {}
  string str() {
    char ns[50];
    sprintf(ns, "(%.1lf %.1lf %.1lf)", x, y, z);
    return string(ns);
  }
};

struct line {
  pos p, q;
  pos vec;
  string str() { return ("(" + p.str() + "-" + q.str() + ")"); }
  line(pos ip, pos iq) {
    p = ip;
    q = iq;
    vec = p.tov(q);
  }
  line() {}
  double dist(pos a) {
    if (p.tov(a).dot(p.tov(q)) < 0)
      return p.tov(a).norm;
    if (q.tov(a).dot(q.tov(p)) < 0)
      return q.tov(a).norm;
    if (p.tov(a).norm < 1e-9)
      return p.tov(a).norm;
    if (q.tov(a).norm < 1e-9)
      return q.tov(a).norm;

    pos pa = p.tov(a);
    double co =
        abs(acos(max(-1.0, min(1.0, pa.dot(vec) / vec.norm / pa.norm))));
    // printf("%lf\\n",pa.dot(vec));
    return pa.norm * sin(co);
  }
};

pos sc[2005];
double sr[2005];

pos tc[2005];
double tr[2005];

int isc[15][2005];

int n, m, r;
int main(void) {
  for (;;) {
    scanf("%d%d%d", &n, &m, &r);
    if (n + m + r == 0)
      break;
    rep(i, n) {
      double x, y, z;
      scanf("%lf%lf%lf%lf", &x, &y, &z, &sr[i]);
      sc[i] = pos(x, y, z);
    }
    rep(i, m) {
      double x, y, z;
      scanf("%lf%lf%lf%lf", &x, &y, &z, &tr[i]);
      tc[i] = pos(x, y, z);
    }
    pos oc;
    {
      double x, y, z;
      scanf("%lf%lf%lf", &x, &y, &z);
      oc = pos(x, y, z);
    }
    memset(isc, 0, sizeof(isc));

    rep(i, m) {
      line a(oc, tc[i]);
      rep(j, n) {
        if (sc[j].tov(oc).norm < sr[j] && sc[j].tov(tc[i]).norm < sr[j])
          continue;
        if (a.dist(sc[j]) > sr[j])
          continue;
        isc[i][j] = 1;
      }
    }
    /*
    rep(i,m){
            line a(oc,tc[i]);
            rep(j,n){
                    printf("%d %d %s %d %s %lf %lf\\n",
                            isc[i][j],
                            i,a.str().c_str(),
                            j,sc[j].str().c_str(),
                            a.dist(sc[j]),
                            sr[j]);
            }
    }*/

    double ans = 0;

    rep(i, 1 << m) {
      int cn = 0;
      rep(j, n) {
        bool b = false;
        rep(k, m) {
          if ((i & (1 << k)) == 0)
            continue;
          if (isc[k][j])
            b = true;
        }
        if (b)
          cn++;
      }
      if (cn > r)
        continue;
      double ns = 0;
      rep(j, m) {
        if ((i & (1 << j)) == 0)
          continue;
        ns += tr[j] / line(oc, tc[j]).vec.norm2;
      }
      // printf("%d %d %lf\\n",i,cn,ns);

      ans = max(ans, ns);
    }
    printf("%f\\n", ans);
  }
  return 0;
}