Problem p00426 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MMP(a, b, c) make_pair(make_pair(a, b), c)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL) - 9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

string def;

int change(string S) {
  int a = 0;
  for (int i = S.size() - 1; i >= 0; i--) {
    a *= 3;
    if (S[i] == 'A')
      a += 0;
    else if (S[i] == 'B')
      a += 1;
    else
      a += 2;
  }
  return a;
}

string change(int a) {
  string S = def;
  for (int i = 0; i < S.size(); i++) {
    if (a % 3 == 0)
      S[i] = 'A';
    else if (a % 3 == 1)
      S[i] = 'B';
    else
      S[i] = 'C';
    a /= 3;
  }
  return S;
}

int main() {
  ios::sync_with_stdio(false);

START:

  int n, m;
  cin >> n >> m;
  if (n == 0 && m == 0)
    return 0;
  string S = "";
  for (int i = 0; i < n; i++)
    S += " ";
  def = S;
  int tmp;
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'A';
  }
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'B';
  }
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'C';
  }

  int ans = INT_MAX;
  set<int> already;
  already.insert(change(S));
  priority_queue<pair<int, int>> que;
  que.push(MP(INT_MAX, change(S)));
  while (!que.empty()) {
    int c = INT_MAX - que.top().first;
    // cout << c << " " << que.top().second << endl;
    if (c > m) {
      cout << -1 << endl;
      break;
    }

    S = change(que.top().second);
    vector<int> A, B, C;
    for (int i = 0; i < S.size(); i++) {
      if (S[i] == 'A')
        A.push_back(i);
      else if (S[i] == 'B')
        B.push_back(i);
      else
        C.push_back(i);
    }
    if (B.size() == 0 && (A.size() == 0 || C.size() == 0)) {
      cout << c << endl;
      break;
    }

    // cout << A.size() << " ";
    // for(int i=0; i<A.size(); i++) cout << A[i] << " ";
    // cout << endl;
    // cout << B.size() << " ";
    // for(int i=0; i<B.size(); i++) cout << B[i] << " ";
    // cout << endl;
    // cout << C.size() << " ";
    // for(int i=0; i<C.size(); i++) cout << C[i] << " ";
    // cout << endl;

    if ((A.size() > 0 && B.size() > 0 && A.back() > B.back()) ||
        (A.size() > 0 && B.size() == 0)) {
      S[A.back()] = 'B';
      if (already.count(change(S)) == 0) {
        already.insert(change(S));
        que.push(MP(INT_MAX - c - 1, change(S)));
      }
      S[A.back()] = 'A';
    }
    if ((A.size() > 0 && B.size() > 0 && A.back() < B.back()) ||
        (A.size() == 0 && B.size() > 0)) {
      S[B.back()] = 'A';
      if (already.count(change(S)) == 0) {
        already.insert(change(S));
        que.push(MP(INT_MAX - c - 1, change(S)));
      }
      S[B.back()] = 'B';
    }
    if ((C.size() > 0 && B.size() > 0 && C.back() > B.back()) ||
        (C.size() > 0 && B.size() == 0)) {
      S[C.back()] = 'B';
      if (already.count(change(S)) == 0) {
        already.insert(change(S));
        que.push(MP(INT_MAX - c - 1, change(S)));
      }
      S[C.back()] = 'C';
    }
    if ((C.size() > 0 && B.size() > 0 && C.back() < B.back()) ||
        (C.size() == 0 && B.size() > 0)) {
      S[B.back()] = 'C';
      if (already.count(change(S)) == 0) {
        already.insert(change(S));
        que.push(MP(INT_MAX - c - 1, change(S)));
      }
      S[B.back()] = 'B';
    }

    que.pop();
    if (que.empty()) {
      cout << -1 << endl;
      break;
    }
  }

  while (!que.empty())
    que.pop();

  goto START;

  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MMP(a, b, c) make_pair(make_pair(a, b), c)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL) - 9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

int main() {
  ios::sync_with_stdio(false);

START:

  int n, m;
  cin >> n >> m;
  if (n == 0 && m == 0)
    return 0;
  string S = "";
  for (int i = 0; i < n; i++)
    S += " ";
  int tmp;
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'A';
  }
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'B';
  }
  cin >> tmp;
  for (int i = 0; i < tmp; i++) {
    int tmp2;
    cin >> tmp2;
    tmp2--;
    S[tmp2] = 'C';
  }

  int ans = INT_MAX;
  set<string> already;
  already.insert(S);
  priority_queue<pair<int, string>> que;
  que.push(MP(INT_MAX, S));
  while (!que.empty()) {
    int c = INT_MAX - que.top().first;
    // cout << c << " " << que.top().second << endl;
    if (c > m) {
      cout << -1 << endl;
      break;
    }

    S = que.top().second;
    vector<int> A, B, C;
    for (int i = 0; i < S.size(); i++) {
      if (S[i] == 'A')
        A.push_back(i);
      else if (S[i] == 'B')
        B.push_back(i);
      else
        C.push_back(i);
    }
    if (B.size() == 0 && (A.size() == 0 || C.size() == 0)) {
      cout << c << endl;
      break;
    }

    // cout << A.size() << " ";
    // for(int i=0; i<A.size(); i++) cout << A[i] << " ";
    // cout << endl;
    // cout << B.size() << " ";
    // for(int i=0; i<B.size(); i++) cout << B[i] << " ";
    // cout << endl;
    // cout << C.size() << " ";
    // for(int i=0; i<C.size(); i++) cout << C[i] << " ";
    // cout << endl;

    if ((A.size() > 0 && B.size() > 0 && A.back() > B.back()) ||
        (A.size() > 0 && B.size() == 0)) {
      S[A.back()] = 'B';
      if (already.count(S) == 0) {
        already.insert(S);
        que.push(MP(INT_MAX - c - 1, S));
      }
      S[A.back()] = 'A';
    }
    if ((A.size() > 0 && B.size() > 0 && A.back() < B.back()) ||
        (A.size() == 0 && B.size() > 0)) {
      S[B.back()] = 'A';
      if (already.count(S) == 0) {
        already.insert(S);
        que.push(MP(INT_MAX - c - 1, S));
      }
      S[B.back()] = 'B';
    }
    if ((C.size() > 0 && B.size() > 0 && C.back() > B.back()) ||
        (C.size() > 0 && B.size() == 0)) {
      S[C.back()] = 'B';
      if (already.count(S) == 0) {
        already.insert(S);
        que.push(MP(INT_MAX - c - 1, S));
      }
      S[C.back()] = 'C';
    }
    if ((C.size() > 0 && B.size() > 0 && C.back() < B.back()) ||
        (C.size() == 0 && B.size() > 0)) {
      S[B.back()] = 'C';
      if (already.count(S) == 0) {
        already.insert(S);
        que.push(MP(INT_MAX - c - 1, S));
      }
      S[B.back()] = 'B';
    }

    que.pop();
    if (que.empty()) {
      cout << -1 << endl;
      break;
    }
  }

  goto START;

  return 0;
}