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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for (int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for (int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<ll, int, int, int> state;

const int MAX_N = 55;
const int MAX_SS = 25;
string s[MAX_N];
ll dis[MAX_N][2][MAX_SS];
int cost[MAX_N], n;

bool palindrome(const string &S) {
  return equal(S.begin(), S.end(), S.rbegin());
}

ll dijkstra() {
  memset(dis, 0x7F, sizeof dis);

  priority_queue<state, vector<state>, greater<state>> pq;
  fori(i, 0, n) {
    pq.emplace(cost[i], i, 0, 0);
    dis[i][0][1] = cost[i];
  }

  ll ans = -1;

  while (!pq.empty()) {
    state cur = pq.top();
    pq.pop();

    ll w;
    int id, type, pos;
    tie(w, id, type, pos) = cur;

    if (w > dis[id][type][pos + 1]) {
      continue;
    }

    string cur_s = s[id];
    string rem = type == 0 ? cur_s.substr(pos, (int)cur_s.size() - pos)
                           : cur_s.substr(0, pos + 1);

    if (palindrome(rem)) {
      ans = w;
      break;
    }

    fori(i, 0, n) {
      string it_s = s[i];
      bool ok = true;

      if (type == 0) {
        for (int j = 0; pos + j < (int)cur_s.size() && j < (int)it_s.size();
             j++) {
          bool match = cur_s[pos + j] == it_s[(int)it_s.size() - j - 1];
          if (!match) {
            ok = false;
            break;
          }
        }
      } else {
        for (int j = 0; pos - j >= 0 && j < (int)it_s.size(); j++) {
          bool match = cur_s[pos - j] == it_s[j];
          if (!match) {
            ok = false;
            break;
          }
        }
      }

      if (ok) {
        state new_state;

        if (type == 0) {
          int needed = cur_s.size() - pos;
          if ((int)it_s.size() >= needed) {
            new_state =
                state(w + cost[i], i, !type, (int)it_s.size() - needed - 1);
          } else {
            new_state = state(w + cost[i], id, type, pos + (int)it_s.size());
          }
        } else {
          int needed = pos + 1;
          if ((int)it_s.size() >= needed) {
            new_state = state(w + cost[i], i, !type, needed);
          } else {
            new_state = state(w + cost[i], id, type, pos - (int)it_s.size());
          }
        }

        if (get<0>(new_state) <
            dis[get<1>(new_state)][get<2>(new_state)][get<3>(new_state) + 1]) {
          dis[get<1>(new_state)][get<2>(new_state)][get<3>(new_state) + 1] =
              get<0>(new_state);
          pq.emplace(new_state);
        }
      }
    }
  }

  return ans;
}

void solve() {
  cin >> n;
  fori(i, 0, n) { cin >> s[i] >> cost[i]; }
  ll ans = dijkstra();
  cout << ans << endl;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for (int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for (int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<ll, int, int, int> state;

const int MAX_N = 55;
const int MAX_SS = 25;
string s[MAX_N];
ll dis[MAX_N][2][MAX_SS];
int cost[MAX_N], n;

bool palindrome(const string &S) {
  return equal(S.begin(), S.end(), S.rbegin());
}

ll dijkstra() {
  memset(dis, 0x7F, sizeof dis);

  priority_queue<state, vector<state>, greater<state>> pq;
  fori(i, 0, n) {
    pq.emplace(cost[i], i, 0, 0);
    dis[i][0][1] = cost[i];
  }

  ll ans = -1;

  while (!pq.empty()) {
    state cur = pq.top();
    pq.pop();

    ll w;
    int id, type, pos;
    tie(w, id, type, pos) = cur;

    if (w > dis[id][type][pos + 1]) {
      continue;
    }

    string cur_s = s[id];
    string rem = type == 0 ? cur_s.substr(pos, (int)cur_s.size() - pos)
                           : cur_s.substr(0, pos + 1);

    if (palindrome(rem)) {
      ans = w;
      break;
    }

    fori(i, 0, n) {
      string it_s = s[i];
      bool ok = true;

      if (type == 0) {
        for (int j = 0; pos + j < (int)cur_s.size() && j < (int)it_s.size();
             j++) {
          bool match = cur_s[pos + j] == it_s[(int)it_s.size() - j - 1];
          if (!match) {
            ok = false;
            break;
          }
        }
      } else {
        for (int j = 0; pos - j >= 0 && j < (int)it_s.size(); j++) {
          bool match = cur_s[pos - j] == it_s[j];
          if (!match) {
            ok = false;
            break;
          }
        }
      }

      if (ok) {
        state new_state;

        if (type == 0) {
          int needed = cur_s.size() - pos;
          if ((int)it_s.size() >= needed) {
            new_state = state(w + cost[i], i, !type, it_s.size() - needed - 1);
          } else {
            new_state = state(w + cost[i], id, type, pos + it_s.size());
          }
        } else {
          int needed = pos + 1;
          if ((int)it_s.size() >= needed) {
            new_state = state(w + cost[i], i, !type, needed);
          } else {
            new_state = state(w + cost[i], id, type, pos - it_s.size());
          }
        }

        if (get<0>(new_state) <
            dis[get<1>(new_state)][get<2>(new_state)][get<3>(new_state)]) {
          pq.emplace(new_state);
        }
      }
    }
  }

  return ans;
}

void solve() {
  cin >> n;
  fori(i, 0, n) { cin >> s[i] >> cost[i]; }
  ll ans = dijkstra();
  cout << ans << endl;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}