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

#include <iostream>
#include <string>
#include <tr1/unordered_set>
#include <vector>

using namespace std;
using namespace std::tr1;
typedef long long ll;

ll s2ll(const string &s) {
  ll x = 0;
  for (int i = 0; i < s.size(); ++i) {
    x = (x << 4) | (s[i] - '0');
  }
  return x;
}

ll make_mask(int left, int right) {
  ll m = 0x1111111111111111ll;
  m &= ~((1ll << (left << 2)) - 1);
  m &= ((1ll << (right << 2)) - 1);
  return m;
}

ll rotate(int k, ll x, ll m) {
  x += m;
  ll c = ((x & (x >> 2)) >> 1) & 0x1111111111111111ll;
  x &= ~(c | (c << 1) | (c << 2) | (c << 3));
  x &= (1ll << (k << 2)) - 1;
  return x;
}

int dfs(int k, ll s, ll g) {
  if (k == 0) {
    return 0;
  }
  if ((s & 15) == (g & 15)) {
    return dfs(k - 1, s >> 4, g >> 4);
  }
  const ll m = 0x1111111111111111ll;
  ll t = s;
  while ((t & 15) != (g & 15)) {
    t = rotate(k, t, m);
  }
  int answer = k;
  for (int i = 1; i <= k; ++i) {
    ll n = (1ll << (i << 2)) - 1;
    answer = min(answer, dfs(k - 1, ((s & ~n) | (t & n)) >> 4, g >> 4));
  }
  return answer + 1;
}

int main() {
  while (true) {
    int k;
    cin >> k;
    if (k == 0) {
      break;
    }
    string s1, s2;
    cin >> s1 >> s2;
    if (s1 == s2) {
      cout << 0 << endl;
      continue;
    }
    ll initial = s2ll(s1), unlocked = s2ll(s2);
    cout << dfs(k, initial, unlocked) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <iostream>
#include <string>
#include <tr1/unordered_set>
#include <vector>

using namespace std;
using namespace std::tr1;
typedef long long ll;

ll s2ll(const string &s) {
  ll x = 0;
  for (int i = 0; i < s.size(); ++i) {
    x = (x << 4) | (s[i] - '0');
  }
  return x;
}

ll make_mask(int left, int right) {
  ll m = 0x1111111111111111ll;
  m &= ~((1ll << (left << 2)) - 1);
  m &= ((1ll << (right << 2)) - 1);
  return m;
}

ll rotate(int k, ll x, ll m) {
  x += m;
  ll c = ((x & (x >> 2)) >> 1) & 0x1111111111111111ll;
  x &= ~(c | (c << 1) | (c << 2) | (c << 3));
  x &= (1ll << (k << 2)) - 1;
  return x;
}

int main() {
  while (true) {
    int k;
    cin >> k;
    if (k == 0) {
      break;
    }
    string s1, s2;
    cin >> s1 >> s2;
    vector<ll> cq1, cq2, nq1, nq2;
    unordered_set<ll> set1, set2;
    cq1.push_back(s2ll(s1));
    set1.insert(cq1[0]);
    cq2.push_back(s2ll(s2));
    set2.insert(cq2[0]);
    int answer = 0;
    while (true) {
      bool finished = false;
      for (int i = 0; i < cq1.size(); ++i) {
        if (set2.find(cq1[i]) != set2.end()) {
          finished = true;
          break;
        }
        for (int left = 0; left < k; ++left) {
          for (int right = left + 1; right <= k; ++right) {
            ll m = make_mask(left, right);
            ll x = cq1[i];
            for (int r = 1; r < 10; ++r) {
              x = rotate(k, x, m);
              if (set1.find(x) != set1.end()) {
                continue;
              }
              set1.insert(x);
              nq1.push_back(x);
            }
          }
        }
      }
      cq1.swap(nq1);
      nq1.clear();
      if (finished) {
        break;
      }
      ++answer;
      for (int i = 0; i < cq2.size(); ++i) {
        if (set1.find(cq2[i]) != set1.end()) {
          finished = true;
          break;
        }
        for (int left = 0; left < k; ++left) {
          for (int right = left + 1; right <= k; ++right) {
            ll m = make_mask(left, right);
            ll x = cq2[i];
            for (int r = 1; r < 10; ++r) {
              x = rotate(k, x, m);
              if (set2.find(x) != set2.end()) {
                continue;
              }
              set2.insert(x);
              nq2.push_back(x);
            }
          }
        }
      }
      cq2.swap(nq2);
      nq2.clear();
      if (finished) {
        break;
      }
      ++answer;
    }
    cout << answer << endl;
  }
  return 0;
}