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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define For(i, n, k) for (int i = (n); i < (k); i++)
#define ALL(a) (a).begin(), (a).end()
int n, cnt = 0;
ll ret;
ll ans[20];
ll x[20], y[20], p[20], dist[20];
int mp[20];    // yでsortした順番に出力してくれる
int train[20]; // 0:なし 1:東西 2:南北
void solve() {
  ret = 0;
  For(i, 0, n) dist[i] = min(abs(x[i]), abs(y[i]));
  // xで左から見る
  int left = -1e8;
  For(i, 0, n) {
    if (train[i] == 2) {
      left = x[i];
    }
    dist[i] = min(dist[i], x[i] - left);
  }
  // xで右から見る
  int right = 1e8;
  for (int i = n - 1; i > -1; i--) {
    if (train[i] == 2) {
      right = x[i];
    }
    dist[i] = min(dist[i], right - x[i]);
  }
  // yで下から見る
  int down = -1e8;
  For(i, 0, n) {
    if (train[mp[i]] == 1) {
      down = y[mp[i]];
    }
    dist[mp[i]] = min(dist[mp[i]], y[mp[i]] - down);
  }
  // yで上から見る
  int up = 1e8;
  for (int i = n - 1; i > -1; i--) {
    if (train[mp[i]] == 1) {
      up = y[mp[i]];
    }
    dist[mp[i]] = min(dist[mp[i]], up - y[mp[i]]);
  }
  For(i, 0, n) ret += dist[i] * p[i];
  ans[cnt] = min(ans[cnt], ret);
  return;
}
void Main() {
  cin >> n;
  vector<pair<int, pair<int, int>>> vec(n);
  For(i, 0, n) {
    cin >> vec[i].first >> vec[i].second.first >> vec[i].second.second;
  }
  sort(ALL(vec));
  // xでsortした順に入れる
  For(i, 0, n) {
    x[i] = vec[i].first;
    y[i] = vec[i].second.first;
    p[i] = vec[i].second.second;
  }
  // yでsortし直す
  sort(ALL(vec),
       [&](auto &l, auto &r) { return l.second.first < r.second.first; });
  // xsortとysortの対応関係を作る
  For(i, 0, n) {
    For(j, 0, n) {
      if (vec[i].first == x[j] && vec[i].second.first == y[j]) {
        mp[i] = j;
        break;
      }
    }
  }
  int p3 = 1;
  fill(ans, ans + n + 1, 1e18);
  For(i, 0, n) p3 *= 3;
  For(i, 0, p3) {
    int x = i;
    cnt = 0;
    For(j, 0, n) {
      train[j] = x % 3;
      x /= 3;
      if (train[j] > 0)
        cnt++;
    }
    solve();
  }
  For(i, 0, n + 1) cout << ans[i] << endl;
}
int main() {
  Main();
  /*
  東方風神録は神が出てくるので当然神ゲー
  */
  return 0;
}

Error: TLE

Fixed submission:

#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define For(i, n, k) for (int i = (n); i < (k); i++)
#define ALL(a) (a).begin(), (a).end()
int n, cnt = 0;
ll ret;
ll ans[20];
ll x[20], y[20], p[20], dist[20];
map<int, int> mp; // yでsortした順番に出力してくれる
int train[20];    // 0:なし 1:東西 2:南北
void solve() {
  ret = 0;
  For(i, 0, n) dist[i] = min(abs(x[i]), abs(y[i]));
  // xで左から見る
  int left = -1e8;
  For(i, 0, n) {
    if (train[i] == 2) {
      left = x[i];
    }
    dist[i] = min(dist[i], x[i] - left);
  }
  // xで右から見る
  int right = 1e8;
  for (int i = n - 1; i > -1; i--) {
    if (train[i] == 2) {
      right = x[i];
    }
    dist[i] = min(dist[i], right - x[i]);
  }
  // yで下から見る
  int down = -1e8;
  For(i, 0, n) {
    if (train[mp[i]] == 1) {
      down = y[mp[i]];
    }
    dist[mp[i]] = min(dist[mp[i]], y[mp[i]] - down);
  }
  // yで上から見る
  int up = 1e8;
  for (int i = n - 1; i > -1; i--) {
    if (train[mp[i]] == 1) {
      up = y[mp[i]];
    }
    dist[mp[i]] = min(dist[mp[i]], up - y[mp[i]]);
  }
  For(i, 0, n) ret += dist[i] * p[i];
  ans[cnt] = min(ans[cnt], ret);
  return;
}
void Main() {
  cin >> n;
  vector<pair<int, pair<int, int>>> vec(n);
  For(i, 0, n) {
    cin >> vec[i].first >> vec[i].second.first >> vec[i].second.second;
  }
  sort(ALL(vec));
  // xでsortした順に入れる
  For(i, 0, n) {
    x[i] = vec[i].first;
    y[i] = vec[i].second.first;
    p[i] = vec[i].second.second;
  }
  // yでsortし直す
  sort(ALL(vec),
       [&](auto &l, auto &r) { return l.second.first < r.second.first; });
  // xsortとysortの対応関係を作る
  For(i, 0, n) {
    For(j, 0, n) {
      if (vec[i].first == x[j] && vec[i].second.first == y[j]) {
        mp[i] = j;
        break;
      }
    }
  }
  int p3 = 1;
  fill(ans, ans + n + 1, 1e18);
  For(i, 0, n) p3 *= 3;
  For(i, 0, p3) {
    int x = i;
    cnt = 0;
    For(j, 0, n) {
      train[j] = x % 3;
      x /= 3;
      if (train[j] > 0)
        cnt++;
    }
    solve();
  }
  For(i, 0, n + 1) cout << ans[i] << endl;
}
int main() {
  Main();
  /*
  東方風神録は神が出てくるので当然神ゲー
  */
  return 0;
}