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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, 1, 0, -1};
// adjust problem by problem
const double EPS = 1e-8;
const double PI = acos(-1.0);
#ifdef __GNUC__
int popcount(int n) { return __builtin_popcount(n); }
int popcount(ll n) { return __builtin_popcountll(n); }
#endif
#ifndef __GNUC__
template <class T> int popcount(T n) {
  int cnt = 0;
  while (n) {
    if (n % 2)
      cnt++;
    n /= 2;
  }
  return cnt;
}
#endif
template <class T> int SIZE(T a) { return a.size(); }
template <class T> string IntToString(T num) {
  string res;
  stringstream ss;
  ss << num;
  return ss.str();
}
template <class T> T StringToInt(string str) {
  T res = 0;
  for (int i = 0; i < SIZE(str); i++)
    res = (res * 10 + str[i] - '0');
  return res;
}
template <class T> T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
bool EQ(double a, double b) { return abs(a - b) < EPS; }
void fastStream() {
  cin.tie(0);
  std::ios_base::sync_with_stdio(0);
}
vector<string> split(string str, char del) {
  vector<string> res;
  for (int i = 0, s = 0; i < SIZE(str); i++) {
    if (str[i] == del) {
      if (i - s != 0)
        res.push_back(str.substr(s, i - s));
      s = i + 1;
    } else if (i == SIZE(str) - 1) {
      res.push_back(str.substr(s));
    }
  }
  return res;
}

typedef vector<pii> vec;
typedef vector<vec> mat;

int sy, sx;
int gy, gx;
int goal[3][3];
// 0->red,1->blue,2->white
mat field(3, vec(3));
int fieldMask;
const int INF = 1 << 30;
set<int> used;
int ary[3][3];

int dcdColor(int a, int b) {
  if (a == 0 && b == 1)
    return 2;
  else if (a == 0 && b == 2)
    return 1;
  else if (a == 1 && b == 0)
    return 2;
  else if (a == 1 && b == 2)
    return 0;
  else if (a == 2 && b == 0)
    return 1;
  else if (a == 2 && b == 1)
    return 0;
}

int toVal(int a, int b) {
  if (a == 0 && b == 1)
    return 0;
  if (a == 0 && b == 2)
    return 1;
  if (a == 1 && b == 0)
    return 2;
  if (a == 1 && b == 2)
    return 3;
  if (a == 2 && b == 0)
    return 4;
  if (a == 2 && b == 1)
    return 5;
  return 6;
}

// maskにvalをset
int setMask(int mask, int pos, int val) {
  for (int i = 0; i < 3; i++) {
    if ((val >> i) & 1)
      mask |= (1 << (3 * pos + i));
    else
      mask &= ~(1 << (3 * pos + i));
  }
  return mask;
}
// maskのposにある値をget
int getVal(int mask, int pos) {
  int res = 0;
  for (int i = 0; i < 3; i++)
    if ((mask >> (3 * pos + i)) & 1)
      res |= (1 << i);
  return res;
}

// // iddfsでgoalに到達できるかどうかを探索
// // 辿りつけなければ-1を返す
int iddfs(int depth, int limDepth, int cy, int cx, int cnt) {
  // 距離を計算
  if (depth == limDepth) {
    if (cnt == 0)
      return depth;
    return -1;
  }
  // 異なる面の数がのこりの移動回数+1以下ならok
  if (cnt > (limDepth - depth) + 1)
    return -1;
  if (abs(cy - gy) + abs(cx - gx) > (limDepth - depth))
    return -1;
  // for(int i=0;i<4;i++){
  //   int ncnt=cnt;
  //   int ny=cy+dy[i],nx=cx+dx[i];
  //   // enable to move
  //   if(ny>=0&&nx>=0&&ny<3&&nx<3){
  //     ncnt-=(field[ny][nx].first!=goal[ny][nx]);
  //     ncnt-=(field[cy][cx].first!=goal[cy][cx]);
  //     pii p1=field[cy][cx];
  //     pii p2=field[ny][nx];
  //     int bMask=fieldMask;
  //     // 移動先の要素を回転させて今の場所へ持ってくる
  //     if(nx!=cx){
  //       field[cy][cx].first=ary[field[ny][nx].first][field[ny][nx].second];
  //       field[cy][cx].second=field[ny][nx].second;
  //       fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,
  //                                       field[cy][cx].second));
  //     }
  //     else if(ny!=cy){
  //       field[cy][cx]=field[ny][nx];
  //       swap(field[cy][cx].first,field[cy][cx].second);
  //       fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,
  //                                       field[cy][cx].second));
  //     }
  //     field[ny][nx].first=field[ny][nx].second=-1;
  //     fieldMask=setMask(fieldMask,ny*3+nx,toVal(field[cy][cx].first,
  //                                     field[cy][cx].second));
  //     if(used.count(fieldMask)==0){
  //       ncnt+=(field[ny][nx].first!=goal[ny][nx]);
  //       ncnt+=(field[cy][cx].first!=goal[cy][cx]);
  //       used.insert(fieldMask);
  //       dfs(depth+1,ny,nx,ncnt);
  //       used.erase(fieldMask);
  //     }
  //     fieldMask=bMask;
  //     // back track
  //     field[cy][cx]=p1;
  //     field[ny][nx]=p2;
  //   }
  // }
  for (int i = 0; i < 4; i++) {
    int ncnt = cnt;
    int ny = cy + dy[i], nx = cx + dx[i];
    // enable to move
    if (ny >= 0 && nx >= 0 && ny < 3 && nx < 3) {
      ncnt -= (field[ny][nx].first != goal[ny][nx]);
      ncnt -= (field[cy][cx].first != goal[cy][cx]);
      pii p1 = field[cy][cx];
      pii p2 = field[ny][nx];
      int bMask = fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if (nx != cx) {
        field[cy][cx].first = ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second = field[ny][nx].second;
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      } else if (ny != cy) {
        field[cy][cx] = field[ny][nx];
        swap(field[cy][cx].first, field[cy][cx].second);
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      }
      field[ny][nx].first = field[ny][nx].second = -1;
      fieldMask = setMask(fieldMask, ny * 3 + nx,
                          toVal(field[ny][nx].first, field[ny][nx].second));
      if (used.count(fieldMask) == 0) {
        ncnt += (field[ny][nx].first != goal[ny][nx]);
        ncnt += (field[cy][cx].first != goal[cy][cx]);
        used.insert(fieldMask);
        int res = iddfs(depth + 1, limDepth, ny, nx, ncnt);
        if (res != -1)
          return res;
        used.erase(fieldMask);
      }
      // back track
      fieldMask = bMask;
      field[cy][cx] = p1;
      field[ny][nx] = p2;
    }
  }
  return -1;
}

int ans;
// dfsでgoalに到達できるかどうかを探索
// 辿りつけなければ-1を返す
void dfs(int depth, int cy, int cx, int cnt) {
  // 距離を計算
  if (cnt == 0) {
    ans = min(ans, depth);
    return;
  }
  if (cnt > (ans - depth) + 1)
    return;
  if (abs(cy - gy) + abs(cx - gx) > (ans - depth))
    return;
  for (int i = 0; i < 4; i++) {
    int ncnt = cnt;
    int ny = cy + dy[i], nx = cx + dx[i];
    // enable to move
    if (ny >= 0 && nx >= 0 && ny < 3 && nx < 3) {
      ncnt -= (field[ny][nx].first != goal[ny][nx]);
      ncnt -= (field[cy][cx].first != goal[cy][cx]);
      pii p1 = field[cy][cx];
      pii p2 = field[ny][nx];
      int bMask = fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if (nx != cx) {
        field[cy][cx].first = ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second = field[ny][nx].second;
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      } else if (ny != cy) {
        field[cy][cx] = field[ny][nx];
        swap(field[cy][cx].first, field[cy][cx].second);
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      }
      field[ny][nx].first = field[ny][nx].second = -1;
      fieldMask = setMask(fieldMask, ny * 3 + nx,
                          toVal(field[ny][nx].first, field[ny][nx].second));
      if (used.count(fieldMask) == 0) {
        ncnt += (field[ny][nx].first != goal[ny][nx]);
        ncnt += (field[cy][cx].first != goal[cy][cx]);
        used.insert(fieldMask);
        dfs(depth + 1, ny, nx, ncnt);
        used.erase(fieldMask);
      }
      fieldMask = bMask;
      // back track
      field[cy][cx] = p1;
      field[ny][nx] = p2;
    }
  }
}

int main() {
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      ary[i][j] = dcdColor(i, j);
  while (cin >> sx >> sy && (sx | sy)) {
    // topfaceがgoalとmatchしたら終了
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        char ch;
        cin >> ch;
        if (ch == 'R')
          goal[i][j] = 0;
        else if (ch == 'B')
          goal[i][j] = 1;
        else if (ch == 'W')
          goal[i][j] = 2;
        else {
          goal[i][j] = -1;
          gy = i, gx = j;
        }
      }
    }
    sy--, sx--;
    // start地点をセット
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        if (i == sy && j == sx) {
          field[i][j] = pii(-1, -1);
          fieldMask = setMask(fieldMask, i * 3 + j, 6);
        } else {
          field[i][j] = pii(2, 0);
          fieldMask = setMask(fieldMask, i * 3 + j, toVal(2, 0));
        }
      }
    }
    ans = 31;
    int cnt = 0;
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++)
        cnt += (field[i][j].first != goal[i][j]);
    used.insert(fieldMask);
    dfs(0, sy, sx, cnt);
    if (ans == 31)
      cout << -1 << endl;
    else
      cout << ans << endl;
    // iddfs
    // int res=-1;
    // for(int d=0;d<=30;d++){
    //   //cout<<d<<" "<<flush;
    //   used.clear();
    //   // start地点をセット
    //   for(int i=0;i<3;i++){
    //     for(int j=0;j<3;j++){
    //       if(i==sy&&j==sx){
    //         field[i][j]=pii(-1,-1);
    //         fieldMask=setMask(fieldMask,i*3+j,6);
    //       }
    //       else{
    //         field[i][j]=pii(2,0);
    //         fieldMask=setMask(fieldMask,i*3+j,toVal(2,0));
    //       }
    //     }
    //   }
    //   int cnt=0;
    //   for(int i=0;i<3;i++)
    //     for(int j=0;j<3;j++)
    //       cnt+=(field[i][j].first!=goal[i][j]);
    //   used.insert(fieldMask);
    //   res=iddfs(0,d,sy,sx,cnt);
    //   if(res!=-1){
    //     res=d;
    //     break;
    //   }
    // }
    // cout<<endl;
    // cout<<res<<endl<<flush;
    // cout<<res<<endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, 1, 0, -1};
// adjust problem by problem
const double EPS = 1e-8;
const double PI = acos(-1.0);
#ifdef __GNUC__
int popcount(int n) { return __builtin_popcount(n); }
int popcount(ll n) { return __builtin_popcountll(n); }
#endif
#ifndef __GNUC__
template <class T> int popcount(T n) {
  int cnt = 0;
  while (n) {
    if (n % 2)
      cnt++;
    n /= 2;
  }
  return cnt;
}
#endif
template <class T> int SIZE(T a) { return a.size(); }
template <class T> string IntToString(T num) {
  string res;
  stringstream ss;
  ss << num;
  return ss.str();
}
template <class T> T StringToInt(string str) {
  T res = 0;
  for (int i = 0; i < SIZE(str); i++)
    res = (res * 10 + str[i] - '0');
  return res;
}
template <class T> T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
bool EQ(double a, double b) { return abs(a - b) < EPS; }
void fastStream() {
  cin.tie(0);
  std::ios_base::sync_with_stdio(0);
}
vector<string> split(string str, char del) {
  vector<string> res;
  for (int i = 0, s = 0; i < SIZE(str); i++) {
    if (str[i] == del) {
      if (i - s != 0)
        res.push_back(str.substr(s, i - s));
      s = i + 1;
    } else if (i == SIZE(str) - 1) {
      res.push_back(str.substr(s));
    }
  }
  return res;
}

typedef vector<pii> vec;
typedef vector<vec> mat;

int sy, sx;
int gy, gx;
int goal[3][3];
// 0->red,1->blue,2->white
mat field(3, vec(3));
int fieldMask;
const int INF = 1 << 30;
set<int> used;
int ary[3][3];

int dcdColor(int a, int b) {
  if (a == 0 && b == 1)
    return 2;
  else if (a == 0 && b == 2)
    return 1;
  else if (a == 1 && b == 0)
    return 2;
  else if (a == 1 && b == 2)
    return 0;
  else if (a == 2 && b == 0)
    return 1;
  else if (a == 2 && b == 1)
    return 0;
}

int toVal(int a, int b) {
  if (a == 0 && b == 1)
    return 0;
  if (a == 0 && b == 2)
    return 1;
  if (a == 1 && b == 0)
    return 2;
  if (a == 1 && b == 2)
    return 3;
  if (a == 2 && b == 0)
    return 4;
  if (a == 2 && b == 1)
    return 5;
  return 6;
}

// maskにvalをset
int setMask(int mask, int pos, int val) {
  for (int i = 0; i < 3; i++) {
    if ((val >> i) & 1)
      mask |= (1 << (3 * pos + i));
    else
      mask &= ~(1 << (3 * pos + i));
  }
  return mask;
}
// maskのposにある値をget
int getVal(int mask, int pos) {
  int res = 0;
  for (int i = 0; i < 3; i++)
    if ((mask >> (3 * pos + i)) & 1)
      res |= (1 << i);
  return res;
}

// // iddfsでgoalに到達できるかどうかを探索
// // 辿りつけなければ-1を返す
int iddfs(int depth, int limDepth, int cy, int cx, int cnt) {
  // 距離を計算
  if (depth == limDepth) {
    if (cnt == 0)
      return depth;
    return -1;
  }
  // 異なる面の数がのこりの移動回数+1以下ならok
  if (cnt > (limDepth - depth) + 1)
    return -1;
  if (abs(cy - gy) + abs(cx - gx) > (limDepth - depth))
    return -1;
  // for(int i=0;i<4;i++){
  //   int ncnt=cnt;
  //   int ny=cy+dy[i],nx=cx+dx[i];
  //   // enable to move
  //   if(ny>=0&&nx>=0&&ny<3&&nx<3){
  //     ncnt-=(field[ny][nx].first!=goal[ny][nx]);
  //     ncnt-=(field[cy][cx].first!=goal[cy][cx]);
  //     pii p1=field[cy][cx];
  //     pii p2=field[ny][nx];
  //     int bMask=fieldMask;
  //     // 移動先の要素を回転させて今の場所へ持ってくる
  //     if(nx!=cx){
  //       field[cy][cx].first=ary[field[ny][nx].first][field[ny][nx].second];
  //       field[cy][cx].second=field[ny][nx].second;
  //       fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,
  //                                       field[cy][cx].second));
  //     }
  //     else if(ny!=cy){
  //       field[cy][cx]=field[ny][nx];
  //       swap(field[cy][cx].first,field[cy][cx].second);
  //       fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,
  //                                       field[cy][cx].second));
  //     }
  //     field[ny][nx].first=field[ny][nx].second=-1;
  //     fieldMask=setMask(fieldMask,ny*3+nx,toVal(field[cy][cx].first,
  //                                     field[cy][cx].second));
  //     if(used.count(fieldMask)==0){
  //       ncnt+=(field[ny][nx].first!=goal[ny][nx]);
  //       ncnt+=(field[cy][cx].first!=goal[cy][cx]);
  //       used.insert(fieldMask);
  //       dfs(depth+1,ny,nx,ncnt);
  //       used.erase(fieldMask);
  //     }
  //     fieldMask=bMask;
  //     // back track
  //     field[cy][cx]=p1;
  //     field[ny][nx]=p2;
  //   }
  // }
  for (int i = 0; i < 4; i++) {
    int ncnt = cnt;
    int ny = cy + dy[i], nx = cx + dx[i];
    // enable to move
    if (ny >= 0 && nx >= 0 && ny < 3 && nx < 3) {
      ncnt -= (field[ny][nx].first != goal[ny][nx]);
      ncnt -= (field[cy][cx].first != goal[cy][cx]);
      pii p1 = field[cy][cx];
      pii p2 = field[ny][nx];
      int bMask = fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if (nx != cx) {
        field[cy][cx].first = ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second = field[ny][nx].second;
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      } else if (ny != cy) {
        field[cy][cx] = field[ny][nx];
        swap(field[cy][cx].first, field[cy][cx].second);
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      }
      field[ny][nx].first = field[ny][nx].second = -1;
      fieldMask = setMask(fieldMask, ny * 3 + nx,
                          toVal(field[ny][nx].first, field[ny][nx].second));
      if (used.count(fieldMask) == 0) {
        ncnt += (field[ny][nx].first != goal[ny][nx]);
        ncnt += (field[cy][cx].first != goal[cy][cx]);
        used.insert(fieldMask);
        int res = iddfs(depth + 1, limDepth, ny, nx, ncnt);
        if (res != -1)
          return res;
        used.erase(fieldMask);
      }
      // back track
      fieldMask = bMask;
      field[cy][cx] = p1;
      field[ny][nx] = p2;
    }
  }
  return -1;
}

int ans;
// dfsでgoalに到達できるかどうかを探索
// 辿りつけなければ-1を返す
void dfs(int depth, int cy, int cx, int cnt) {
  // 距離を計算
  if (cnt == 0) {
    ans = min(ans, depth);
    return;
  }
  if (cnt > (ans - depth) + 1)
    return;
  if (abs(cy - gy) + abs(cx - gx) > (ans - depth))
    return;
  for (int i = 0; i < 4; i++) {
    int ncnt = cnt;
    int ny = cy + dy[i], nx = cx + dx[i];
    // enable to move
    if (ny >= 0 && nx >= 0 && ny < 3 && nx < 3) {
      ncnt -= (field[ny][nx].first != goal[ny][nx]);
      ncnt -= (field[cy][cx].first != goal[cy][cx]);
      pii p1 = field[cy][cx];
      pii p2 = field[ny][nx];
      int bMask = fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if (nx != cx) {
        field[cy][cx].first = ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second = field[ny][nx].second;
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      } else if (ny != cy) {
        field[cy][cx] = field[ny][nx];
        swap(field[cy][cx].first, field[cy][cx].second);
        fieldMask = setMask(fieldMask, cy * 3 + cx,
                            toVal(field[cy][cx].first, field[cy][cx].second));
      }
      field[ny][nx].first = field[ny][nx].second = -1;
      fieldMask = setMask(fieldMask, ny * 3 + nx,
                          toVal(field[ny][nx].first, field[ny][nx].second));
      if (used.count(fieldMask) == 0) {
        ncnt += (field[ny][nx].first != goal[ny][nx]);
        ncnt += (field[cy][cx].first != goal[cy][cx]);
        used.insert(fieldMask);
        dfs(depth + 1, ny, nx, ncnt);
        used.erase(fieldMask);
      }
      fieldMask = bMask;
      // back track
      field[cy][cx] = p1;
      field[ny][nx] = p2;
    }
  }
}

int main() {

  // ll mask=0;
  // mask=setMask(mask,0,7);
  // mask=setMask(mask,0,5);
  // mask=setMask(mask,1,7);
  // mask=setMask(mask,1,5);
  // //cout<<bitset<10>(mask)<<endl;
  // // mask=setMask(mask,1,2);
  // cout<<getVal(mask,0)<<endl;
  // cout<<getVal(mask,1)<<endl;
  // return 0;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      ary[i][j] = dcdColor(i, j);
  while (cin >> sx >> sy && (sx | sy)) {
    // topfaceがgoalとmatchしたら終了
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        char ch;
        cin >> ch;
        if (ch == 'R')
          goal[i][j] = 0;
        else if (ch == 'B')
          goal[i][j] = 1;
        else if (ch == 'W')
          goal[i][j] = 2;
        else {
          goal[i][j] = -1;
          gy = i, gx = j;
        }
      }
    }
    sy--, sx--;
    // start地点をセット
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        if (i == sy && j == sx) {
          field[i][j] = pii(-1, -1);
          fieldMask = setMask(fieldMask, i * 3 + j, 6);
        } else {
          field[i][j] = pii(2, 0);
          fieldMask = setMask(fieldMask, i * 3 + j, toVal(2, 0));
        }
      }
    }
    ans = 31;
    int cnt = 0;
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++)
        cnt += (field[i][j].first != goal[i][j]);
    // cout<<bitset<32>(fieldMask)<<endl;
    // used.insert(fieldMask);
    //  dfs(0,sy,sx,cnt);
    //  if(ans==31)cout<<-1<<endl;
    //  else cout<<ans<<endl;
    int res = -1;
    for (int d = 0; d <= 30; d++) {
      // cout<<d<<" "<<flush;
      used.clear();
      // start地点をセット
      for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
          if (i == sy && j == sx) {
            field[i][j] = pii(-1, -1);
            fieldMask = setMask(fieldMask, i * 3 + j, 6);
          } else {
            field[i][j] = pii(2, 0);
            fieldMask = setMask(fieldMask, i * 3 + j, toVal(2, 0));
          }
        }
      }
      int cnt = 0;
      for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
          cnt += (field[i][j].first != goal[i][j]);
      used.insert(fieldMask);
      res = iddfs(0, d, sy, sx, cnt);
      if (res != -1) {
        res = d;
        break;
      }
    }
    // cout<<endl;
    cout << res << endl << flush;
    // cout<<res<<endl;
  }
  return 0;
}