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

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

using namespace std;

typedef long long ll;
typedef complex<double> P;

#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define DEBUG(x) cout << #x << ": " << (x) << endl

#define N_MAX 10
int n;
P ps[N_MAX + 1];
int tg, tw;
P start, goal;
double pslen[N_MAX + 1];
double pslensum[N_MAX * 2 + 1];

int pai, pbi, sti;
P pa, pb;

double minestval = 1e18;
int minestpai = -1, minestpbi = -1;
bool hack = false;

double calc() {
  double result = 0.0;
  if (pai != sti) {
    result += abs(pa - start) * tw;
  }
  if (pai == sti) {
    if (sti != pbi) {
      double tmp = 0.0;
      if (sti < pbi)
        tmp += (pslensum[pbi - 1] - pslensum[sti]) * tg;
      else
        tmp += (pslensum[pbi + n - 1] - pslensum[sti]) * tg;
      tmp += abs(ps[sti + 1] - start) * tg;
      tmp += abs(pb - ps[pbi]) * tg;

      double tmp2 = 0.0;
      if (sti > pbi)
        tmp2 += (pslensum[sti - 1] - pslensum[pbi]) * tg;
      else
        tmp2 += (pslensum[sti + n - 1] - pslensum[pbi]) * tg;
      tmp2 += abs(start - ps[sti]) * tg;
      tmp2 += abs(ps[pbi + 1] - pb) * tg;

      result += min(tmp, tmp2);
    } else {
      result += abs(pb - start) * tg;
    }
  } else {
    if (pai != pbi) {
      double tmp = 0.0;
      if (pai < pbi)
        tmp += (pslensum[pbi - 1] - pslensum[pai]) * tg;
      else
        tmp += (pslensum[pbi + n - 1] - pslensum[pai]) * tg;
      tmp += abs(ps[pai + 1] - pa) * tg;
      tmp += abs(pb - ps[pbi]) * tg;

      double tmp2 = 0.0;
      if (pai > pbi)
        tmp2 += (pslensum[pai - 1] - pslensum[pbi]) * tg;
      else
        tmp2 += (pslensum[pai + n - 1] - pslensum[pbi]) * tg;
      tmp2 += abs(pa - ps[pai]) * tg;
      tmp2 += abs(ps[pbi + 1] - pb) * tg;

      result += min(tmp, tmp2);
    } else {
      result += abs(pb - pa) * tg;
    }
  }
  result += abs(goal - pb) * tw;
  if (!hack && result < minestval) {
    minestval = result;
    minestpai = pai;
    minestpbi = pbi;
  }
  return result;
}

int T = 10;

double solve2() {
  double result = 1e18;
  REP(i, n) {
    if (hack && i != minestpbi)
      continue;
    pbi = i;
    double left = 0.0;
    double right = 1.0;
    REP(_, T) {
      double midl = (left * 2.0 + right) / 3.0;
      pb = ps[i] + (ps[i + 1] - ps[i]) * midl;
      double resl = calc();
      double midr = (left + right * 2.0) / 3.0;
      pb = ps[i] + (ps[i + 1] - ps[i]) * midr;
      double resr = calc();
      if (resl < resr)
        right = midr;
      else
        left = midl;
    }
    pb = ps[i] + (ps[i + 1] - ps[i]) * left;
    result = min(result, calc());
  }
  return result;
}

double solve() {
  // determine PointA
  double result = 1e18;
  REP(i, n) {
    if (hack && i != minestpai)
      continue;
    // edge from ps[i] to ps[i+1]
    pai = i;
    double left = 0.0;
    double right = 1.0;
    REP(_, T) {
      double midl = (left * 2.0 + right) / 3.0;
      pa = ps[i] + (ps[i + 1] - ps[i]) * midl;
      double resl = solve2();
      double midr = (left + right * 2.0) / 3.0;
      pa = ps[i] + (ps[i + 1] - ps[i]) * midr;
      double resr = solve2();
      if (resl < resr)
        right = midr;
      else
        left = midl;
    }
    pa = ps[i] + (ps[i + 1] - ps[i]) * left;
    result = min(result, solve2());
  }
  return result;
}

int main() {
  cout.precision(20);
  while (true) {
    // input
    cin >> n;
    if (!n)
      break;
    int x, y;
    REP(i, n) {
      cin >> x >> y;
      ps[i] = P(x, y);
    }
    ps[n] = ps[0];
    cin >> tg >> tw;
    cin >> x >> y;
    start = P(x, y);
    cin >> x >> y;
    goal = P(x, y);

    REP(i, n) pslen[i] = abs(ps[i + 1] - ps[i]);
    REP(i, 2 * n + 1) {
      pslensum[i] = pslen[i % n];
      if (i != 0)
        pslensum[i] += pslensum[i - 1];
    }
    REP(i, n) {
      if (abs((conj(ps[i + 1] - ps[i]) * (start - ps[i])).imag()) < 1e-9) {
        sti = i;
        break;
      }
    }
    minestval = 1e18;
    T = 20;
    hack = false;
    solve();
    T = 100;
    hack = true;
    double result = solve();
    cout << fixed << result << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

using namespace std;

typedef long long ll;
typedef complex<double> P;

#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define DEBUG(x) cout << #x << ": " << (x) << endl

#define N_MAX 10
int n;
P ps[N_MAX + 1];
int tg, tw;
P start, goal;
double pslen[N_MAX + 1];
double pslensum[N_MAX * 2 + 1];

int pai, pbi, sti;
P pa, pb;

double calc() {
  double result = 0.0;
  if (pai != sti) {
    result += abs(pa - start) * tw;
  }
  if (pai == sti) {
    if (sti != pbi) {
      double tmp = 0.0;
      if (sti < pbi)
        tmp += (pslensum[pbi - 1] - pslensum[sti]) * tg;
      else
        tmp += (pslensum[pbi + n - 1] - pslensum[sti]) * tg;
      tmp += abs(ps[sti + 1] - start) * tg;
      tmp += abs(pb - ps[pbi]) * tg;

      double tmp2 = 0.0;
      if (sti > pbi)
        tmp2 += (pslensum[sti - 1] - pslensum[pbi]) * tg;
      else
        tmp2 += (pslensum[sti + n - 1] - pslensum[pbi]) * tg;
      tmp2 += abs(start - ps[sti]) * tg;
      tmp2 += abs(ps[pbi + 1] - pb) * tg;

      result += min(tmp, tmp2);
    } else {
      result += abs(pb - start) * tg;
    }
  } else {
    if (pai != pbi) {
      double tmp = 0.0;
      if (pai < pbi)
        tmp += (pslensum[pbi - 1] - pslensum[pai]) * tg;
      else
        tmp += (pslensum[pbi + n - 1] - pslensum[pai]) * tg;
      tmp += abs(ps[pai + 1] - pa) * tg;
      tmp += abs(pb - ps[pbi]) * tg;

      double tmp2 = 0.0;
      if (pai > pbi)
        tmp2 += (pslensum[pai - 1] - pslensum[pbi]) * tg;
      else
        tmp2 += (pslensum[pai + n - 1] - pslensum[pbi]) * tg;
      tmp2 += abs(pa - ps[pai]) * tg;
      tmp2 += abs(ps[pbi + 1] - pb) * tg;

      result += min(tmp, tmp2);
    } else {
      result += abs(pb - pa) * tg;
    }
  }
  result += abs(goal - pb) * tw;
  return result;
}

#define T 60

double solve2() {
  double result = 1e18;
  REP(i, n) {
    pbi = i;
    double left = 0.0;
    double right = 1.0;
    REP(_, T) {
      double midl = (left * 2.0 + right) / 3.0;
      pb = ps[i] + (ps[i + 1] - ps[i]) * midl;
      double resl = calc();
      double midr = (left + right * 2.0) / 3.0;
      pb = ps[i] + (ps[i + 1] - ps[i]) * midr;
      double resr = calc();
      if (resl < resr)
        right = midr;
      else
        left = midl;
    }
    pb = ps[i] + (ps[i + 1] - ps[i]) * left;
    result = min(result, calc());
  }
  return result;
}

double solve() {
  // determine PointA
  double result = 1e18;
  REP(i, n) {
    // edge from ps[i] to ps[i+1]
    pai = i;
    double left = 0.0;
    double right = 1.0;
    REP(_, T) {
      double midl = (left * 2.0 + right) / 3.0;
      pa = ps[i] + (ps[i + 1] - ps[i]) * midl;
      double resl = solve2();
      double midr = (left + right * 2.0) / 3.0;
      pa = ps[i] + (ps[i + 1] - ps[i]) * midr;
      double resr = solve2();
      if (resl < resr)
        right = midr;
      else
        left = midl;
    }
    pa = ps[i] + (ps[i + 1] - ps[i]) * left;
    result = min(result, solve2());
  }
  return result;
}

int main() {
  cout.precision(20);
  while (true) {
    // input
    cin >> n;
    if (!n)
      break;
    int x, y;
    REP(i, n) {
      cin >> x >> y;
      ps[i] = P(x, y);
    }
    ps[n] = ps[0];
    cin >> tg >> tw;
    cin >> x >> y;
    start = P(x, y);
    cin >> x >> y;
    goal = P(x, y);

    REP(i, n) pslen[i] = abs(ps[i + 1] - ps[i]);
    REP(i, 2 * n + 1) {
      pslensum[i] = pslen[i % n];
      if (i != 0)
        pslensum[i] += pslensum[i - 1];
    }
    REP(i, n) {
      if (abs((conj(ps[i + 1] - ps[i]) * (start - ps[i])).imag()) < 1e-9) {
        sti = i;
        break;
      }
    }

    double result = solve();
    cout << fixed << result << endl;
  }
  return 0;
}