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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

typedef complex<double> P;
#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

// OÏ
double cross(P a, P b) { return (a.real() * b.imag() - a.imag() * b.real()); }
// àÏ
double dot(P a, P b) { return (a.real() * b.real() + a.imag() * b.imag()); }

// »ÝÌxNgÆAÚ_ÌÊu©çAÌxNgðÔ·
P calcNextVector(P p, P v) {
  // ÚüxNg
  P v2(-v.imag(), v.real());
  // ÚüÉ¼ÈPÊxNg
  P v3 = P(-v2.imag(), v2.real());
  v3 /= abs(v3);
  // ü«ðà¤É·é
  if (cross(v3, v2) < 0) {
    v3 = -v3;
  }
  return p - 2 * dot(p, v3) * v3;
}

// _a,bðÊé¼üÆ_cÌÔÌ£
double distance_l_p(P a, P b, P c) {
  return abs(cross(b - a, c - a)) / abs(b - a);
}
// a,bðÊé¼üÆ¼a1,´_ÉÊu·é~ÆÌð_ðßé
vector<P> calcCrossPoint(P a, P b) {
  double dlp = distance_l_p(a, b, P(0, 0));
  double x = sqrt(1 - dlp * dlp);
  P c = a - b;
  P d = c / abs(c);

  vector<P> v;
  v.push_back(d * x);
  v.push_back(-d * x);
  return v;
}
// _cª¼üabãÉ é©È¢©
int is_point_on_line(P a, P b, P c) { return EQ(cross(b - a, c - a), 0.0); }
int main() {

  double D;
  double px, py, vx, vy;
  while (cin >> D && !EQ(D, 0.0)) {
    double sumDist = 0;
    cin >> px >> py >> vx >> vy;
    P p = P(px, py);
    P v = P(vx, vy);
    double a = (dot(P(0, 0) - p, v)) / (abs(P(0, 0) - p) * abs(v));
    if (EQ(a, -1)) {
      //	double dist=abs(
      double dist = abs(p - P(0, 0));
      dist = 2 - dist;
      if (EQ(dist, D) || dist < D) {
        printf("%lf\\n", dist);
      } else {
        cout << "impossible" << endl;
      }
    } else if (EQ(a, 1)) {
      double dist = abs(p - P(0, 0));
      if (EQ(dist, D) || dist < D) {
        printf("%lf\\n", dist);
      } else {
        cout << "impossible" << endl;
      }
    } else
      cout << "impossible" << endl;

    // bool ok=true;
    // while(1){
    //	// ~ÆÌð_ðvZ
    //	vector<P> ret = calcCrossPoint(p,v);
    //	P op;
    //	if(EQV(((ret[0]-p)/abs((ret[0]-p))),(v/abs(v)))){
    //		op=ret[0];
    //	}
    //	else{
    //		op=ret[1];
    //	}
    //	// £ðvZ
    //	double dist=abs(op-p);

    //	// ´_ðÊé©Åêí¯
    //	if(is_point_on_line(op,p,P(0,0))){
    //		double g=abs(P(0,0)-p);
    //		if(!EQ(sumDist+g,D)&&sumDist+g>D){
    //			ok=false;
    //			break;
    //		}
    //		else{
    //			sumDist+=g;
    //			ok=true;
    //			break;
    //		}
    //	}
    //	else{
    //		if(EQ(sumDist+dist,D)||sumDist+dist>D){
    //			ok=false;
    //			break;
    //		}
    //		else{
    //			sumDist+=dist;
    //			v=calcNextVector(v,op);
    //			p=op;
    //		}
    //	}
    //}
    // if(ok){
    //	printf("%lf\\n",sumDist);
    //}
    // else
    //	cout<<"impossible"<<endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

typedef complex<double> P;
#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

// OÏ
double cross(P a, P b) { return (a.real() * b.imag() - a.imag() * b.real()); }
// àÏ
double dot(P a, P b) { return (a.real() * b.real() + a.imag() * b.imag()); }

// »ÝÌxNgÆAÚ_ÌÊu©çAÌxNgðÔ·
P calcNextVector(P p, P v) {
  // ÚüxNg
  P v2(-v.imag(), v.real());
  // ÚüÉ¼ÈPÊxNg
  P v3 = P(-v2.imag(), v2.real());
  v3 /= abs(v3);
  // ü«ðà¤É·é
  if (cross(v3, v2) < 0) {
    v3 = -v3;
  }
  return p - 2 * dot(p, v3) * v3;
}

// _a,bðÊé¼üÆ_cÌÔÌ£
double distance_l_p(P a, P b, P c) {
  return abs(cross(b - a, c - a)) / abs(b - a);
}
// a,bðÊé¼üÆ¼a1,´_ÉÊu·é~ÆÌð_ðßé
vector<P> calcCrossPoint(P a, P b) {
  double dlp = distance_l_p(a, b, P(0, 0));
  double x = sqrt(1 - dlp * dlp);
  P c = a - b;
  P d = c / abs(c);

  vector<P> v;
  v.push_back(d * x);
  v.push_back(-d * x);
  return v;
}
// _cª¼üabãÉ é©È¢©
int is_point_on_line(P a, P b, P c) { return EQ(cross(b - a, c - a), 0.0); }
int main() {

  double D;
  double px, py, vx, vy;
  while (cin >> D && !EQ(D, 0.0)) {
    double sumDist = 0;
    cin >> px >> py >> vx >> vy;
    P p = P(px, py);
    P v = P(vx, vy);
    bool ok = true;
    while (1) {
      // ~ÆÌð_ðvZ
      vector<P> ret = calcCrossPoint(p, v);
      P op;
      if (EQV(((ret[0] - p) / abs((ret[0] - p))), (v / abs(v)))) {
        op = ret[0];
      } else {
        op = ret[1];
      }
      // £ðvZ
      double dist = abs(op - p);

      // ´_ðÊé©Åêí¯
      if (is_point_on_line(op, p, P(0, 0))) {
        double g = abs(P(0, 0) - p);
        if (!EQ(sumDist + g, D) && sumDist + g > D) {
          ok = false;
          break;
        } else {
          sumDist += g;
          ok = true;
          break;
        }
      } else {
        if (EQ(sumDist + dist, D) || sumDist + dist > D) {
          ok = false;
          break;
        } else {
          if (dist < 0.001)
            break;
          sumDist += dist;
          v = calcNextVector(v, op);
          p = op;
        }
      }
    }
    if (ok) {
      printf("%lf\\n", sumDist);
    } else
      cout << "impossible" << endl;
  }

  return 0;
}