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

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

/*
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define DEB 0

int board[7][7]; //1base
int sx[2], sy[2];
static const int dx[] = {0,0,1,-1};
static const int dy[] = {1,-1,0,0};

int calc(int y, int x){
    switch(board[y][x]){
    case 1: return abs(2-y)+abs(2-x);
    case 2: return abs(2-y)+abs(3-x);
    case 3: return abs(2-y)+abs(4-x);
    case 4: return abs(3-y)+abs(1-x);
    case 5: return abs(3-y)+abs(2-x);
    case 6: return abs(3-y)+abs(3-x);
    case 7: return abs(3-y)+abs(4-x);
    case 8: return abs(3-y)+abs(5-x);
    case 9: return abs(4-y)+abs(2-x);
    case 10: return abs(4-y)+abs(3-x);
    case 11: return abs(4-y)+abs(4-x);
    }
    return -1;
}
int dist(void){
    int ret = 0;
    if( board[1][3] ) ret += calc(1,3);
    rep(i,3) if( board[2][2+i] ) ret += calc(2,2+i);
    rep(i,5) if( board[3][1+i] ) ret += calc(3,1+i);
    rep(i,3) if( board[4][2+i] ) ret += calc(4,2+i);
    if( board[5][3] ) ret += calc(5,3);
    return ret;
}
bool isgoal(void){
    if( board[1][3]!=0 ) return false;
    rep(i,3) if( board[2][2+i]!=i+1 ) return false;
    rep(i,5) if( board[3][1+i]!=i+4 ) return false;
    rep(i,3) if( board[4][2+i]!=i+9 ) return false;
    if( board[5][3]!=0 ) return false;
    return true;
}

bool dfs(int cnt, int LIM, int py, int px){
    if( isgoal() ) return true;
    if( cnt+dist()>LIM ) return false;

    rep(i,2){
        rep(k,4){
            int tx = sx[i] + dx[k];
            int ty = sy[i] + dy[k];
            if( board[ty][tx]==-1 || ty==py&&tx==px ) continue;
            swap(board[sy[i]][sx[i]], board[ty][tx]);
            swap(sx[i], tx); swap(sy[i],ty);
            if( dfs(cnt+1, LIM, ty, tx) ) return true;
            swap(sx[i], tx); swap(sy[i],ty);
            swap(board[sy[i]][sx[i]] ,board[ty][tx]);
        }
    }
    return false;
}
int solve(void){
    int ttx[2], tty[2];
    int tb[7][7];
    rep(i,2) ttx[i]=sx[i], tty[i]=sy[i];
    rep(i,7)rep(j,7) tb[i][j] = board[i][j];

    for(int lim = 0; lim < 21; lim++){
        rep(i,2) sx[i]=ttx[i], sy[i]=tty[i];
        rep(i,7) rep(j,7) board[i][j] = tb[i][j];
        if( dfs(0,lim,-1,-1) ) return lim;
    }
    return -1;
}
int main(){
    for(;;){
        memset(board, -1, sizeof(board));
        int sz = 0;

        scanf("%d",&board[1][3]); if( board[1][3]==-1 ) break;
        rep(i,3) scanf("%d",&board[2][2+i]);
        rep(i,5) scanf("%d",&board[3][1+i]);
        rep(i,3) scanf("%d",&board[4][2+i]);
        scanf("%d",&board[5][3]);

        // find space
        if( board[1][3]==0 ){ sx[sz]=3; sy[sz]=1; sz++; }
        rep(i,3) if( board[2][2+i]==0 ) { sx[sz]=2+i; sy[sz]=2; sz++; }
        rep(i,5) if( board[3][1+i]==0 ) { sx[sz]=1+i; sy[sz]=3; sz++; }
        rep(i,3) if( board[4][2+i]==0 ) { sx[sz]=2+i; sy[sz]=4; sz++; }
        if( board[5][3]==0 ){ sx[sz]=3; sy[sz]=5; sz++; }

        //printf("hoge:%d\\n",dist());
        int ans = solve();
        if( ans!=-1 ) printf("%d\\n",ans); else puts("NA");
    }
    return 0;
}
*/

//-------------------------------------------------------

#define N 5
#define REP(i, n) for (int i = 0; i < (int)n; i++)
#define LIMIT 20

static const int T[12][2] = {{-1, -1}, {1, 1}, {1, 2}, {1, 3}, {2, 0}, {2, 1},
                             {2, 2},   {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}};
static const int g[N][N] = {{-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}};

class Puzzle {
public:
  int C[N][N], mdist; // manhatta distance
  Puzzle() {}

  bool swapAdj(int si, int sj, int ti, int tj) {
    if (ti < 0 || tj < 0 || ti >= N || tj >= N)
      return false;
    if (C[ti][tj] <= 0)
      return false;
    swap(C[ti][tj], C[si][sj]);
    int tti = T[C[si][sj]][0];
    int ttj = T[C[si][sj]][1];
    // mdist -= max(tti, ti)-min(tti, ti) + max(ttj, tj)-min(ttj, tj);
    // mdist += max(tti, si)-min(tti, si) + max(ttj, sj)-min(ttj, sj);
    // mdist -= abs(tti-ti)+abs(ttj-tj);
    // mdist += abs(tti-si)+abs(ttj-sj);
    return true;
  }

  bool isGoal() {
    REP(i, N) REP(j, N) if (g[i][j] != C[i][j]) return false;
    return true;
  }

  int getMD() { // get initial manhattan distance
    int sum = 0;
    int ti, tj;
    REP(i, 5) REP(j, 5) {
      if (C[i][j] <= 0)
        continue;
      ti = T[C[i][j]][0];
      tj = T[C[i][j]][1];
      // sum += (max(ti, i)-min(ti, i) + max(tj, j) - min(tj, j));
      sum += abs(ti - i) + abs(tj - j);
    }
    return sum;
  }
};

int limit;

bool dfs(int depth, Puzzle P) {
  if (P.isGoal())
    return true;
  if (depth + P.getMD() > limit)
    return false;

  static const int di[4] = {0, -1, 0, 1};
  static const int dj[4] = {1, 0, -1, 0};

  REP(i, N) REP(j, N) {
    if (P.C[i][j] != 0)
      continue;
    REP(r, 4) {
      Puzzle v = P;
      if (!v.swapAdj(i, j, i + di[r], j + dj[r]))
        continue;
      if (dfs(depth + 1, v))
        return true;
    }
  }

  return false;
}

int idp(Puzzle source) {
  for (limit = 0; limit <= LIMIT; limit++) {
    // source.mdist = source.getMD();
    if (dfs(0, source))
      return limit;
  }
  return INT_MAX;
}

int main() {
  Puzzle P;
  int top;

  while (1) {
    cin >> top;
    if (top == -1)
      break;
    REP(j, N) P.C[0][j] = -1;
    P.C[0][2] = top;
    for (int i = 1; i < N; i++)
      REP(j, N) {
        if ((i == 1 || i == 3) && (j == 0 || j == 4))
          P.C[i][j] = -1;
        else if (i == 4 && j != 2)
          P.C[i][j] = -1;
        else
          cin >> P.C[i][j];
      }

    int cost = idp(P);
    if (cost == INT_MAX)
      cout << "NA" << endl;
    else
      cout << cost << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define DEB 0

/*
  1 = [2][2]
  2 = [2][3]
  3 = [2][4]
  4 = [3][1]
  5 = [3][2]
  6 = [3][3]
  7 = [3][4]
  8 = [3][5]
  9 = [4][2]
  10= [4][3]
  11= [4][4]
*/
int board[7][7]; // 1base
int sx[2], sy[2];
static const int dx[] = {0, 0, 1, -1};
static const int dy[] = {1, -1, 0, 0};

/*
(y,x)
 */
int calc(int y, int x) {
  switch (board[y][x]) {
  case 1:
    return abs(2 - y) + abs(2 - x);
  case 2:
    return abs(2 - y) + abs(3 - x);
  case 3:
    return abs(2 - y) + abs(4 - x);
  case 4:
    return abs(3 - y) + abs(1 - x);
  case 5:
    return abs(3 - y) + abs(2 - x);
  case 6:
    return abs(3 - y) + abs(3 - x);
  case 7:
    return abs(3 - y) + abs(4 - x);
  case 8:
    return abs(3 - y) + abs(5 - x);
  case 9:
    return abs(4 - y) + abs(2 - x);
  case 10:
    return abs(4 - y) + abs(3 - x);
  case 11:
    return abs(4 - y) + abs(4 - x);
  }
  return -1;
}
int dist(void) {
  int ret = 0;
  if (board[1][3])
    ret += calc(1, 3);
  rep(i, 3) if (board[2][2 + i]) ret += calc(2, 2 + i);
  rep(i, 5) if (board[3][1 + i]) ret += calc(3, 1 + i);
  rep(i, 3) if (board[4][2 + i]) ret += calc(4, 2 + i);
  if (board[5][3])
    ret += calc(5, 3);
  return ret;
}
bool isgoal(void) {
  if (board[1][3] != 0)
    return false;
  rep(i, 3) if (board[2][2 + i] != i + 1) return false;
  rep(i, 5) if (board[3][1 + i] != i + 4) return false;
  rep(i, 3) if (board[4][2 + i] != i + 9) return false;
  if (board[5][3] != 0)
    return false;
  return true;
}

bool dfs(int cnt, int LIM, int py, int px) {
  if (LIM < cnt)
    return false;
  if (isgoal())
    return true;
  if (cnt + dist() > 23)
    return false;

  rep(i, 2) {
    rep(k, 4) {
      int tx = sx[i] + dx[k];
      int ty = sy[i] + dy[k];
      if (board[ty][tx] == -1 || ty == py && tx == px)
        continue;
      swap(board[sy[i]][sx[i]], board[ty][tx]);
      swap(sx[i], tx);
      swap(sy[i], ty);
      if (dfs(cnt + 1, LIM, ty, tx))
        return true;
      swap(sx[i], tx);
      swap(sy[i], ty);
      swap(board[sy[i]][sx[i]], board[ty][tx]);
    }
  }
  return false;
}
int solve(void) {
  int ttx[2], tty[2];
  rep(i, 2) ttx[i] = sx[i], tty[i] = sy[i];

  for (int lim = 0; lim < 21; lim++) {
    rep(i, 2) sx[i] = ttx[i], sy[i] = tty[i];
    if (dfs(0, lim, -1, -1))
      return lim;
  }
  return -1;
}
int main() {
  for (;;) {
    memset(board, -1, sizeof(board));
    int sz = 0;

    scanf("%d", &board[1][3]);
    if (board[1][3] == -1)
      break;
    rep(i, 3) scanf("%d", &board[2][2 + i]);
    rep(i, 5) scanf("%d", &board[3][1 + i]);
    rep(i, 3) scanf("%d", &board[4][2 + i]);
    scanf("%d", &board[5][3]);

    // find space
    if (board[1][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 1;
      sz++;
    }
    rep(i, 3) if (board[2][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 2;
      sz++;
    }
    rep(i, 5) if (board[3][1 + i] == 0) {
      sx[sz] = 1 + i;
      sy[sz] = 3;
      sz++;
    }
    rep(i, 3) if (board[4][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 4;
      sz++;
    }
    if (board[5][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 5;
      sz++;
    }

    int ans = solve();
    if (ans != -1)
      printf("%d\\n", ans);
    else
      puts("NA");
  }
  return 0;
}