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

#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

int fie[5][5];
int o_fie[5][5] = {
    -1, -1, 0, -1, -1, -1, 1,  2,      3,  -1, 4,  5,
    6,  7,  8, -1, 9,  10, 11, -1 - 1, -1, 0,  -1, -1,
};

int ox[12], oy[12], zx[2], zy[2], zcnt;
int res;
bool flag;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

void dfs(int v, int dist, int pd, int pu) {
  if (dist == 0) {
    flag = true;
    res = min(res, v);
    return;
  }
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 2; j++) {
      if (pu == j && (pd + 2) % 4 == i)
        continue;
      int nx = zx[j] + dx[i], ny = zy[j] + dy[i];
      if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5) {
        if (fie[nx][ny] <= 0)
          continue;
        int ch = fie[nx][ny];
        int ndist = dist;
        ndist -= abs(ox[ch] - nx) + abs(oy[ch] - ny);
        swap(fie[nx][ny], fie[zx[j]][zy[j]]);
        ndist += abs(ox[ch] - zx[j]) + abs(oy[ch] - zy[j]);
        zx[j] += dx[i];
        zy[j] += dy[i];
        if (v + 1 + ndist <= res)
          dfs(v + 1, ndist, i, j);
        zx[j] -= dx[i];
        zy[j] -= dy[i];
        swap(fie[nx][ny], fie[zx[j]][zy[j]]);
      }
    }
  }
}
int dist;

int main(void) {
  for (int i = 0; i < 5; i++) {
    for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
      ox[o_fie[i][j]] = j;
      oy[o_fie[i][j]] = i;
    }
  }
  while (1) {
    memset(fie, -1, sizeof(fie));
    dist = 0;
    zcnt = 0;
    for (int i = 0; i < 5; i++) {
      for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
        scanf("%d", &fie[j][i]);
        if (fie[j][i] == -1)
          return 0;
      }
    }
    for (int i = 0; i < 5; i++) {
      for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
        int v = fie[j][i];
        if (v == 0) {
          zx[zcnt] = j;
          zy[zcnt++] = i;
        } else
          dist += abs(ox[v] - j) + abs(oy[v] - i);
      }
    }
    if (dist > 20) {
      printf("NA\\n");
    } else {
      int i = 0;
      flag = false;
      res = 20;
      dfs(0, dist, -1, -1);
      if (flag) {
        printf("%d\\n", res);
      }
      if (!flag)
        printf("NA\\n");
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

int fie[5][5];
int o_fie[5][5] = {
    -1, -1, 0, -1, -1, -1, 1,  2,      3,  -1, 4,  5,
    6,  7,  8, -1, 9,  10, 11, -1 - 1, -1, 0,  -1, -1,
};

int ox[12], oy[12], zx[2], zy[2], zcnt;
int res;
bool flag;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

void dfs(int v, int dist, int pd, int pu) {
  if (flag)
    return;
  if (dist == 0) {
    flag = true;
    return;
  }
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 2; j++) {
      if (pu == j && (pd + 2) % 4 == i)
        continue;
      int nx = zx[j] + dx[i], ny = zy[j] + dy[i];
      if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5) {
        if (fie[nx][ny] <= 0)
          continue;
        int ch = fie[nx][ny];
        int ndist = dist;
        ndist -= abs(ox[ch] - nx) + abs(oy[ch] - ny);
        swap(fie[nx][ny], fie[zx[j]][zy[j]]);
        ndist += abs(ox[ch] - zx[j]) + abs(oy[ch] - zy[j]);
        zx[j] += dx[i];
        zy[j] += dy[i];
        if (v + 1 + ndist <= res)
          dfs(v + 1, ndist, i, j);
        swap(fie[nx][ny], fie[zx[j]][zy[j]]);
        zx[j] -= dx[i];
        zy[j] -= dy[i];
      }
    }
  }
}
int dist;

int main(void) {
  for (int i = 0; i < 5; i++) {
    for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
      ox[o_fie[i][j]] = j;
      oy[o_fie[i][j]] = i;
    }
  }
  while (1) {
    memset(fie, -1, sizeof(fie));
    dist = 0;
    zcnt = 0;
    for (int i = 0; i < 5; i++) {
      for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
        scanf("%d", &fie[j][i]);
        if (fie[j][i] == -1)
          return 0;
      }
    }
    for (int i = 0; i < 5; i++) {
      for (int j = abs(2 - i); j <= 4 - abs(2 - i); j++) {
        int v = fie[j][i];
        if (v == 0) {
          zx[zcnt] = j;
          zy[zcnt++] = i;
        } else
          dist += abs(ox[v] - j) + abs(oy[v] - i);
      }
    }
    if (dist > 20) {
      printf("NA\\n");
    } else {
      int i = 0;
      flag = false;
      while (i + dist <= 20) {
        res = i + dist;
        dfs(0, dist, -1, -1);
        if (flag) {
          printf("%d\\n", i + dist);
          break;
        }
      }
      if (!flag)
        printf("NA\\n");
    }
  }
  return 0;
}