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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

class Dice {
public:
  void roll(char dst) {
    for (int i = 0; i < 6; i++)
      work[i] = color[i];
    switch (dst) {
    case 'E':
      setColor(work[3], work[1], work[0], work[5], work[4], work[2]);
      break;
    case 'S':
      setColor(work[1], work[5], work[2], work[3], work[0], work[4]);
      break;
    case 'N':
      setColor(work[4], work[0], work[2], work[3], work[5], work[1]);
      break;
    case 'W':
      setColor(work[2], work[1], work[5], work[0], work[4], work[3]);
      break;
    }
  };

  char getTop() { return color[0]; }

  void setColor(char n0, char n1, char n2, char n3, char n4, char n5) {
    color[0] = n0;
    color[1] = n1;
    color[2] = n2;
    color[3] = n3;
    color[4] = n4;
    color[5] = n5;
  }

  void init() { setColor('W', 'R', 'B', 'B', 'R', 'W'); }

  void to_empty() { setColor('E', 'E', 'E', 'E', 'E', 'E'); }

  char color[6], work[6];
};

struct Info {
  Dice board[3][3];
  int num_step;
};

int first_row, first_col;
int diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};
Info goal;

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= 2 && col >= 0 && col <= 2)
    return true;
  else {
    return false;
  }
}

int calcDiff(Info info) {

  int ret = 0;

  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      if (info.board[row][col].getTop() != goal.board[row][col].getTop()) {
        ret++;
      }
    }
  }

  return ret;
}

bool FLG;

void recursive(Info info, int max_depth, int empty_row, int empty_col,
               int pre_row, int pre_col) {

  if (FLG)
    return;

  int tmp_diff = calcDiff(info);

  if (tmp_diff == 0) {
    FLG = true;
    return;
  }

  if (info.num_step + tmp_diff > max_depth + 1)
    return;

  int adj_row, adj_col;
  info.num_step++;

  Dice tmp;

  for (int i = 0; i < 4; i++) {
    adj_row = empty_row + diff_row[i];
    adj_col = empty_col + diff_col[i];

    if (!rangeCheck(adj_row, adj_col))
      continue;
    if (adj_row == pre_row && adj_col == pre_col)
      continue;

    tmp = info.board[adj_row][adj_col];

    switch (i) {
    case 0:
      info.board[adj_row][adj_col].roll('S');
      break;
    case 1:
      info.board[adj_row][adj_col].roll('E');
      break;
    case 2:
      info.board[adj_row][adj_col].roll('W');
      break;
    case 3:
      info.board[adj_row][adj_col].roll('N');
      break;
    }

    swap(info.board[empty_row][empty_col], info.board[adj_row][adj_col]);
    recursive(info, max_depth, adj_row, adj_col, empty_row, empty_col);

    info.board[empty_row][empty_col].to_empty();
    info.board[adj_row][adj_col] = tmp;
  }
}

void func() {

  first_row--;
  first_col--;

  char buf[2];

  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      scanf("%s", buf);
      goal.board[row][col].color[0] = buf[0];
    }
  }

  Info first;
  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++)
      first.board[row][col].init();
  }
  first.board[first_row][first_col].to_empty();
  first.num_step = 0;

  FLG = false;
  int ans;

  for (int max_depth = 0; max_depth <= 30; max_depth++) {
    recursive(first, max_depth, first_row, first_col, -1, -1);
    if (FLG) {
      ans = max_depth;
      break;
    }
  }

  if (FLG) {
    printf("%d\\n", ans);
  } else {
    printf("-1\\n");
  }
}

int main() {

  while (true) {
    scanf("%d %d", &first_col, &first_row);
    if (first_col == 0 && first_row == 0)
      break;

    func();
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

class Dice {
public:
  void roll(char dst) {
    for (int i = 0; i < 6; i++)
      work[i] = color[i];
    switch (dst) {
    case 'E':
      setColor(work[3], work[1], work[0], work[5], work[4], work[2]);
      break;
    case 'S':
      setColor(work[1], work[5], work[2], work[3], work[0], work[4]);
      break;
    case 'N':
      setColor(work[4], work[0], work[2], work[3], work[5], work[1]);
      break;
    case 'W':
      setColor(work[2], work[1], work[5], work[0], work[4], work[3]);
      break;
    }
  };

  char getTop() { return color[0]; }

  void setColor(char n0, char n1, char n2, char n3, char n4, char n5) {
    color[0] = n0;
    color[1] = n1;
    color[2] = n2;
    color[3] = n3;
    color[4] = n4;
    color[5] = n5;
  }

  void init() { setColor('W', 'R', 'B', 'B', 'R', 'W'); }

  void to_empty() { setColor('E', 'E', 'E', 'E', 'E', 'E'); }

  char color[6], work[6];
};

struct Info {
  Dice board[3][3];
  int empty_row, empty_col, num_step, pre_row, pre_col;
};

int POW[10];
int first_row, first_col;
int diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};
Info goal;

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= 2 && col >= 0 && col <= 2)
    return true;
  else {
    return false;
  }
}

int calcDiff(Info info) {

  int ret = 0;

  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      if (info.board[row][col].getTop() != goal.board[row][col].getTop()) {
        ret++;
      }
    }
  }

  return ret;
}

void copyInfo(Info &to, Info from) {

  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      to.board[row][col] = from.board[row][col];
    }
  }

  to.num_step = from.num_step + 1;
}

int ans;

void recursive(Info info) {

  int tmp_diff = calcDiff(info);

  if (tmp_diff == 0) {
    ans = min(ans, info.num_step);
    return;
  }

  if (info.num_step + tmp_diff > min(ans, 30))
    return;

  int adj_row, adj_col;

  for (int i = 0; i < 4; i++) {
    adj_row = info.empty_row + diff_row[i];
    adj_col = info.empty_col + diff_col[i];

    if (!rangeCheck(adj_row, adj_col))
      continue;
    if (adj_row == info.pre_row && adj_col == info.pre_col)
      continue;

    Info next_info;
    copyInfo(next_info, info);

    switch (i) {
    case 0:
      next_info.board[adj_row][adj_col].roll('S');
      break;
    case 1:
      next_info.board[adj_row][adj_col].roll('E');
      break;
    case 2:
      next_info.board[adj_row][adj_col].roll('W');
      break;
    case 3:
      next_info.board[adj_row][adj_col].roll('N');
      break;
    }

    next_info.board[info.empty_row][info.empty_col] =
        next_info.board[adj_row][adj_col];
    next_info.board[adj_row][adj_col].to_empty();
    next_info.empty_row = adj_row;
    next_info.empty_col = adj_col;
    next_info.pre_row = info.empty_row;
    next_info.empty_col = info.empty_col;

    recursive(next_info);
  }
}

void func() {

  first_row--;
  first_col--;

  char buf[2];

  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      scanf("%s", buf);
      goal.board[row][col].color[0] = buf[0];
    }
  }

  Info first;
  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++)
      first.board[row][col].init();
  }
  first.board[first_row][first_col].to_empty();
  first.empty_row = first_row;
  first.empty_col = first_col;
  first.num_step = 0;
  first.pre_row = -1;
  first.pre_col = -1;

  ans = BIG_NUM;

  recursive(first);

  if (ans != BIG_NUM) {
    printf("%d\\n", ans);
  } else {
    printf("-1\\n");
  }
}

int main() {

  for (int i = 0; i < 10; i++)
    POW[i] = pow(4, i);

  while (true) {
    scanf("%d %d", &first_col, &first_row);
    if (first_col == 0 && first_row == 0)
      break;

    func();
  }

  return 0;
}