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

#include <cmath>
#include <iomanip>
#include <iostream>

using namespace std;

int n;
double r;
double theta;
int x[20];
int y[20];
double dp[20][20];
double buf[20][20];
bool check_angle_buf[20][20][20];
double dist_buf[20][20];

double dist(int i, int j) {
  int dx1 = x[j] - x[i];
  int dy1 = y[j] - y[i];
  return sqrt(dx1 * dx1 + dy1 * dy1);
}

bool check_angle(int i, int j, int k) {
  int dx1 = x[j] - x[i];
  int dy1 = y[j] - y[i];
  int dx2 = x[k] - x[j];
  int dy2 = y[k] - y[j];
  double arg = acos((dx1 * dx2 + dy1 * dy2) / (dist(i, j) * dist(j, k)));
  return arg <= theta;
}

void dumpdp() {
  for (int i = -1; i < n; ++i) {
    for (int j = -1; j < n; ++j) {
      if (i == -1) {
        if (j == -1)
          continue;
        cout << setw(10) << j;
        continue;
      }
      if (j == -1) {
        cout << i;
        continue;
      }
      if (dp[i][j] > 10000) {
        cout << "        --";
      } else {
        cout << setw(10) << setprecision(2) << fixed << dp[i][j];
      }
      // cout << "(" <<setw(4) << setprecision(2) << fixed << dist_buf[i][j];
    }
    cout << endl;
  }
  cout << endl;
}

int main() {
  cin >> n;
  cin >> r >> theta;
  theta = theta * M_PI / 180;
  for (int i = 0; i < n; ++i) {
    cin >> x[i] >> y[i];
  }

  int cmax = (int)r + 1;

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      dp[i][j] = 10000000;
      dist_buf[i][j] = dist(i, j);
      for (int k = 0; k < n; ++k) {
        check_angle_buf[i][j][k] = check_angle(i, j, k);
        // cout << i << j << k << " " << (check_angle_buf[i][j][k] ? "OK": "NG")
        // << endl;
      }
    }
  }
  double mind = r + 1;
  for (int i = 1; i < n; ++i) {
    dp[0][i] = dist(0, i);
    mind = min(mind, dp[0][i]);
    for (int j = 0; j < n; ++j) {
      dp[i][j] = 100000000;
      buf[0][j] = 100000000;
      buf[i][j] = 100000000;
    }
  }

  if (mind > r) {
    cout << 0 << endl;
    return 0;
  }
  dp[0][0] = 1000000;

  int c;
  for (c = 1; c <= cmax; ++c) {
    // dumpdp();
    for (int k = 0; k < n; ++k) {
      for (int j = 0; j < n; ++j) {
        if (j == k)
          continue;
        double d = dist_buf[j][k];
        double tmp = 1000000000;
        for (int i = 0; i < n; ++i) {
          if (j == i || k == i)
            continue;
          if (!check_angle_buf[i][j][k])
            continue;
          tmp = min(tmp, d + dp[i][j]);
        }
        buf[j][k] = tmp;
      }
    }
    double minr = r + 1;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dp[i][j] = buf[i][j];
        minr = min(minr, dp[i][j]);
        buf[i][j] = 10000000;
      }
    }
    if (minr > r)
      break;
  }
  cout << c << endl;
}


Error: TLE

Fixed submission:

#include <cmath>
#include <iomanip>
#include <iostream>

using namespace std;

int n;
double r;
double theta;
int x[20];
int y[20];
double dp[20][20];
double buf[20][20];

bool check_angle(int i, int j, int k) {
  int dx1 = x[j] - x[i];
  int dy1 = y[j] - y[i];
  int dx2 = x[k] - x[j];
  int dy2 = y[k] - y[j];
  double l1 = sqrt(dx1 * dx1 + dy1 * dy1);
  double l2 = sqrt(dx2 * dx2 + dy2 * dy2);
  double arg = acos((dx1 * dx2 + dy1 * dy2) / (l1 * l2));
  return arg <= theta;
}

double dist(int i, int j) {
  int dx1 = x[j] - x[i];
  int dy1 = y[j] - y[i];
  return sqrt(dx1 * dx1 + dy1 * dy1);
}

void dumpdp() {
  for (int i = -1; i < n; ++i) {
    for (int j = -1; j < n; ++j) {
      if (i == -1) {
        if (j == -1)
          continue;
        cout << setw(10) << j;
        continue;
      }
      if (j == -1) {
        cout << i;
        continue;
      }
      if (dp[i][j] > 10000) {
        cout << "        --";
      } else {
        cout << setw(10) << setprecision(2) << fixed << dp[i][j];
      }
    }
    cout << endl;
  }
  cout << endl;
}

int main() {
  cin >> n;
  cin >> r >> theta;
  theta = theta * M_PI / 180;
  for (int i = 0; i < n; ++i) {
    cin >> x[i] >> y[i];
  }

  int cmax = (int)r + 1;

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      dp[i][j] = 10000000;
    }
  }
  double mind = r + 1;
  for (int i = 1; i < n; ++i) {
    dp[0][i] = dist(0, i);
    mind = min(mind, dp[0][i]);
    for (int j = 0; j < n; ++j) {
      dp[i][j] = 100000000;
    }
  }
  if (mind > r) {
    cout << 0 << endl;
    return 0;
  }
  dp[0][0] = 1000000;

  int c;
  for (c = 1; c <= cmax; ++c) {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        buf[i][j] = 10000000;
      }
    }
    // dumpdp();
    for (int k = 0; k < n; ++k) {
      for (int j = 0; j < n; ++j) {
        if (j == k)
          continue;
        double d = dist(j, k);
        double tmp = 1000000000;
        for (int i = 0; i < n; ++i) {
          if (j == i || k == i)
            continue;
          if (!check_angle(i, j, k))
            continue;
          tmp = min(tmp, d + dp[i][j]);
        }
        buf[j][k] = tmp;
      }
    }
    double minr = r + 1;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dp[i][j] = buf[i][j];
        minr = min(minr, dp[i][j]);
      }
    }
    if (minr > r)
      break;
  }
  cout << c << endl;
}