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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#ifdef _LOCAL_DEBUG
#include "templates/debug.h"
#else
#define debug(...)
#endif

bool is_palindrome(const string &s) {
  if (s.size() <= 1u)
    return true;
  int l = 0, r = (int)s.size() - 1;
  while (l < r) {
    if (s[l] != s[r])
      return false;
    l++, r--;
  }
  return true;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<string> strs(n);
  vector<ll> cost(n);
  for (int i = 0; i < n; i++) {
    cin >> strs[i] >> cost[i];
  }
  // map<pair<string, string>, ll> dis;
  map<pair<string, string>, ll> dis;
  queue<tuple<string, string, ll>> q;
  ll ans = 2e18;
  for (int i = 0; i < n; i++) {
    if (is_palindrome(strs[i]))
      ans = min(ans, cost[i]);
    else {
      q.push({strs[i], string(""), cost[i]});
      dis[{strs[i], string("")}] = cost[i];
    }
  }
  while (q.size()) {
    auto [s1, s2, d] = q.front();
    q.pop();
    if (s2.empty()) {
      assert(s1.size() > 0);
      for (int i = 0; i < n; i++) {
        size_t m = min(s1.size(), strs[i].size());
        bool ok = true;
        for (size_t j = 0, k = strs[i].size() - 1; j < m; j++, k--) {
          if (s1[j] != strs[i][k]) {
            ok = false;
            break;
          }
        }
        if (ok) {
          if (s1.size() == strs[i].size()) {
            ans = min(ans, d + cost[i]);
          } else if (s1.size() < strs[i].size()) {
            string new_str = strs[i].substr(0, strs[i].size() - m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else if (auto it = dis.find({"", new_str});
                     it == dis.end() || it->second > d + cost[i]) {
              q.push({"", new_str, d + cost[i]});
              dis[{"", new_str}] = d + cost[i];
            }
          } else {
            string new_str = s1.substr(m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else if (auto it = dis.find({"", new_str});
                     it == dis.end() || it->second > d + cost[i]) {
              q.push({new_str, "", d + cost[i]});
              dis[{new_str, ""}] = d + cost[i];
            }
          }
        }
      }
    } else {
      assert(s1.empty());
      for (int i = 0; i < n; i++) {
        size_t m = min(strs[i].size(), s2.size());
        bool ok = true;
        for (size_t k = s2.size() - 1, j = 0; j < m; j++, k--) {
          if (strs[i][j] != s2[k]) {
            ok = false;
            break;
          }
        }
        if (ok) {
          if (strs[i].size() == s2.size()) {
            ans = min(ans, d + cost[i]);
          } else if (strs[i].size() < s2.size()) {
            string new_str = s2.substr(0, s2.size() - m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else if (auto it = dis.find({"", new_str});
                     it == dis.end() || it->second > d + cost[i]) {
              q.push({"", new_str, d + cost[i]});
              dis[{"", new_str}] = d + cost[i];
            }
          } else {
            string new_str = strs[i].substr(m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else if (auto it = dis.find({"", new_str});
                     it == dis.end() || it->second > d + cost[i]) {
              q.push({new_str, "", d + cost[i]});
              dis[{new_str, ""}] = d + cost[i];
            }
          }
        }
      }
    }
  }
  if (ans >= 2e18)
    cout << "-1\\n";
  else
    cout << ans << '\\n';
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#ifdef _LOCAL_DEBUG
#include "templates/debug.h"
#else
#define debug(...)
#endif

bool is_palindrome(const string &s) {
  if (s.size() <= 1u)
    return true;
  int l = 0, r = (int)s.size() - 1;
  while (l < r) {
    if (s[l] != s[r])
      return false;
    l++, r--;
  }
  return true;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<string> strs(n);
  vector<ll> cost(n);
  for (int i = 0; i < n; i++) {
    cin >> strs[i] >> cost[i];
  }
  queue<tuple<string, string, ll>> q;
  ll ans = 2e18;
  for (int i = 0; i < n; i++) {
    if (is_palindrome(strs[i]))
      ans = min(ans, cost[i]);
    else
      q.push({strs[i], string(""), cost[i]});
  }
  while (q.size()) {
    auto [s1, s2, d] = q.front();
    q.pop();
    if (s2.empty()) {
      assert(s1.size() > 0);
      for (int i = 0; i < n; i++) {
        size_t m = min(s1.size(), strs[i].size());
        bool ok = true;
        for (size_t j = 0, k = strs[i].size() - 1; j < m; j++, k--) {
          if (s1[j] != strs[i][k]) {
            ok = false;
            break;
          }
        }
        if (ok) {
          if (s1.size() == strs[i].size()) {
            ans = min(ans, d + cost[i]);
          } else if (s1.size() < strs[i].size()) {
            string new_str = strs[i].substr(0, strs[i].size() - m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else
              q.push({"", new_str, d + cost[i]});
          } else {
            string new_str = s1.substr(m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else
              q.push({new_str, "", d + cost[i]});
          }
        }
      }
    } else {
      assert(s1.empty());
      for (int i = 0; i < n; i++) {
        size_t m = min(strs[i].size(), s2.size());
        bool ok = true;
        for (size_t k = s2.size() - 1, j = 0; j < m; j++, k--) {
          if (strs[i][j] != s2[k]) {
            ok = false;
            break;
          }
        }
        if (ok) {
          if (strs[i].size() == s2.size()) {
            ans = min(ans, d + cost[i]);
          } else if (strs[i].size() < s2.size()) {
            string new_str = s2.substr(0, s2.size() - m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else
              q.push({"", new_str, d + cost[i]});
          } else {
            string new_str = strs[i].substr(m);
            if (is_palindrome(new_str))
              ans = min(ans, d + cost[i]);
            else
              q.push({new_str, "", d + cost[i]});
          }
        }
      }
    }
  }
  if (ans >= 2e18)
    cout << "-1\\n";
  else
    cout << ans << '\\n';
  return 0;
}