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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long lli;
typedef vector<lli> vll;
typedef vector<bool> vbl;
typedef vector<vector<lli>> mat;
typedef vector<vector<bool>> matb;
typedef vector<string> vst;
typedef pair<lli, lli> pll;
typedef pair<double, double> pdd;

mat f(4, vll(4));
mat g(4, vll(4));
lli md = 0;
const lli dx[] = {1, 0, -1, 0};
const lli dy[] = {0, 1, 0, -1};
lli lim = 0;
lli ans = 100;
lli x, y;

vll px, py;
vll fx, fy;
vll gx, gy;
map<mat, lli> m;
map<mat, lli> w;
bool flag = false;

bool isin(lli x, lli y) { return x >= 0 && x < 4 && y >= 0 && y < 4; }

lli m_dist(lli p, lli i, lli j) { return abs(i - px[p]) + abs(j - py[p]); }

void dfs(lli md, lli s, lli x, lli y) {
  if (md + s > lim)
    return;
  if (m.find(f) != m.end()) {
    if (m[f] > s)
      m[f] = s;
    else
      return;
  } else {
    m[f] = s;
  }
  if (s > lim / 2)
    return;
  for (lli i = 0; i < 4; i++) {
    if (isin(x + dx[i], y + dy[i])) {
      swap(f[x + dx[i]][y + dy[i]], f[x][y]);
      dfs(md + m_dist(f[x][y], x, y) - m_dist(f[x][y], x + dx[i], y + dy[i]),
          s + 1, x + dx[i], y + dy[i]);
      swap(f[x + dx[i]][y + dy[i]], f[x][y]);
    }
  }
}

void dfs2(lli md, lli s, lli x, lli y) {
  if (md + s > lim)
    return;
  if (w.find(g) != w.end()) {
    if (w[g] > s)
      w[g] = s;
    else
      return;
  } else {
    w[g] = s;
  }
  if (m.find(g) != m.end()) {
    ans = min(ans, s + m[g]);
    flag = true;
  }
  if (s > lim / 2)
    return;
  for (lli i = 0; i < 4; i++) {
    if (isin(x + dx[i], y + dy[i])) {
      swap(g[x + dx[i]][y + dy[i]], g[x][y]);
      dfs2(md + m_dist(g[x][y], x, y) - m_dist(g[x][y], x + dx[i], y + dy[i]),
           s + 1, x + dx[i], y + dy[i]);
      swap(g[x + dx[i]][y + dy[i]], g[x][y]);
    }
  }
}

int main() {
  for (lli i = 0; i < 4; i++)
    for (lli j = 0; j < 4; j++)
      cin >> f[i][j];

  fx = vll(16);
  fy = vll(16);
  for (lli i = 1; i < 16; i++) {
    fx[i] = (i - 1) / 4;
    fy[i] = (i - 1) % 4;
  }
  px = fx;
  py = fy;

  for (lli i = 0; i < 4; i++) {
    for (lli j = 0; j < 4; j++) {
      if (f[i][j]) {
        md += m_dist(f[i][j], i, j);
      } else {
        x = i;
        y = j;
      }
    }
  }
  for (lli i = 0; i < 4; i++)
    for (lli j = 0; j < 4; j++)
      g[i][j] = (i * 4 + j + 1) % 16;
  gx = vll(16);
  gy = vll(16);
  for (lli i = 0; i < 4; i++) {
    for (lli j = 0; j < 4; j++) {
      gx[f[i][j]] = i;
      gy[f[i][j]] = j;
    }
  }

  for (lli i = md; i <= 46; i++) {
    lim = i;
    m = map<mat, lli>();
    w = map<mat, lli>();
    px = fx;
    py = fy;
    dfs(md, 0, x, y);
    px = gx;
    py = gy;
    dfs2(md, 0, 3, 3);
    if (flag) {
      cout << ans << endl;
      return 0;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long lli;
typedef vector<lli> vll;
typedef vector<bool> vbl;
typedef vector<vector<lli>> mat;
typedef vector<vector<bool>> matb;
typedef vector<string> vst;
typedef pair<lli, lli> pll;
typedef pair<double, double> pdd;

mat f(4, vll(4));
mat g(4, vll(4));
lli md = 0;
const lli dx[] = {1, 0, -1, 0};
const lli dy[] = {0, 1, 0, -1};
lli lim = 0;
lli ans = 100;
lli x, y;

vll px, py;
vll fx, fy;
vll gx, gy;
map<mat, lli> m;
map<mat, lli> w;
bool flag = false;

bool isin(lli x, lli y) { return x >= 0 && x < 4 && y >= 0 && y < 4; }

lli m_dist(lli p, lli i, lli j) { return abs(i - px[p]) + abs(j - py[p]); }

void dfs(lli md, lli s, lli x, lli y) {
  if (md + s > lim)
    return;
  if (m.find(f) != m.end()) {
    if (m[f] > s)
      m[f] = s;
    else
      return;
  } else {
    m[f] = s;
  }
  if (s >= lim / 2)
    return;
  for (lli i = 0; i < 4; i++) {
    if (isin(x + dx[i], y + dy[i])) {
      swap(f[x + dx[i]][y + dy[i]], f[x][y]);
      dfs(md + m_dist(f[x][y], x, y) - m_dist(f[x][y], x + dx[i], y + dy[i]),
          s + 1, x + dx[i], y + dy[i]);
      swap(f[x + dx[i]][y + dy[i]], f[x][y]);
    }
  }
}

void dfs2(lli md, lli s, lli x, lli y) {
  if (md + s > lim)
    return;
  if (w.find(g) != w.end()) {
    if (w[g] > s)
      w[g] = s;
    else
      return;
  } else {
    w[g] = s;
  }
  if (m.find(g) != m.end()) {
    ans = min(ans, s + m[g]);
    flag = true;
  }
  if (s > lim / 2)
    return;
  for (lli i = 0; i < 4; i++) {
    if (isin(x + dx[i], y + dy[i])) {
      swap(g[x + dx[i]][y + dy[i]], g[x][y]);
      dfs2(md + m_dist(g[x][y], x, y) - m_dist(g[x][y], x + dx[i], y + dy[i]),
           s + 1, x + dx[i], y + dy[i]);
      swap(g[x + dx[i]][y + dy[i]], g[x][y]);
    }
  }
}

int main() {
  for (lli i = 0; i < 4; i++)
    for (lli j = 0; j < 4; j++)
      cin >> f[i][j];

  fx = vll(16);
  fy = vll(16);
  for (lli i = 1; i < 16; i++) {
    fx[i] = (i - 1) / 4;
    fy[i] = (i - 1) % 4;
  }
  px = fx;
  py = fy;

  for (lli i = 0; i < 4; i++) {
    for (lli j = 0; j < 4; j++) {
      if (f[i][j]) {
        md += m_dist(f[i][j], i, j);
      } else {
        x = i;
        y = j;
      }
    }
  }
  for (lli i = 0; i < 4; i++)
    for (lli j = 0; j < 4; j++)
      g[i][j] = (i * 4 + j + 1) % 16;
  gx = vll(16);
  gy = vll(16);
  for (lli i = 0; i < 4; i++) {
    for (lli j = 0; j < 4; j++) {
      gx[f[i][j]] = i;
      gy[f[i][j]] = j;
    }
  }

  for (lli i = md; i <= 46; i++) {
    lim = i;
    m = map<mat, lli>();
    w = map<mat, lli>();
    px = fx;
    py = fy;
    dfs(md, 0, x, y);
    px = gx;
    py = gy;
    dfs2(md, 0, 3, 3);
    if (flag) {
      cout << ans << endl;
      return 0;
    }
  }
  return 0;
}