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

/* こんなウンコードで通ったらしぇか行く */

#include <stdio.h>
#include <string.h>

#define EMPTY 0
#define YET_DELIVERED 1
#define CHURCH 2
#define ALREADY_DELIVERED 3

#define CHURCH_INDEX 30

enum direction { SOUTH, EAST, WEST, NORTH };

typedef struct house {
  struct house *next[4];
  int index;
} House;

int house_bits;
House map[10][10];

int rec(House *house, int depth) {
  int i;
  int sum = 0;
  House *now_house;

  for (i = 0; i < 4; i++) {
    now_house = house->next[i];

    while (now_house != NULL) {
      if (now_house->index == CHURCH_INDEX) {
        if (depth == house_bits)
          return 1;
      } else {
        int bit;
        int cond;

        bit = 1 << now_house->index;
        cond = ((bit & depth) == 0);

        if (cond) {
          sum += rec(now_house, bit | depth);
          break;
        }
      }

      now_house = now_house->next[i];
    }
  }

  return sum;
}

int main() {
  while (1) {
    int i;
    int m, n;
    int church_x;
    int church_y;
    int now_ind;
    House *x_prevs[10];

    scanf("%d %d", &m, &n);
    if ((m & n) == 0)
      return 0;

    now_ind = 0;
    memset(map, 0, sizeof(map));
    memset(x_prevs, 0, sizeof(x_prevs));

    for (i = 0; i < n; i++) {
      int j;
      House *y_prev = NULL;

      for (j = 0; j < m; j++) {
        int p;

        scanf("%d", &p);

        if (p == CHURCH) {
          church_x = j;
          church_y = i;

          map[i][j].index = CHURCH_INDEX;

          map[i][j].next[NORTH] = x_prevs[j];
          map[i][j].next[WEST] = y_prev;

          if (x_prevs[j]) {
            x_prevs[j]->next[SOUTH] = &map[i][j];
          }

          if (y_prev) {
            y_prev->next[EAST] = &map[i][j];
          }

          x_prevs[j] = &map[i][j];
          y_prev = &map[i][j];
        } else if (p == YET_DELIVERED) {
          map[i][j].index = now_ind;

          map[i][j].next[NORTH] = x_prevs[j];
          map[i][j].next[WEST] = y_prev;

          if (x_prevs[j]) {
            x_prevs[j]->next[SOUTH] = &map[i][j];
          }

          if (y_prev) {
            y_prev->next[EAST] = &map[i][j];
          }

          x_prevs[j] = &map[i][j];
          y_prev = &map[i][j];

          ++now_ind;
        }
      }

      if (y_prev) {
        y_prev->next[EAST] = NULL;
      }
    }

    for (i = 0; i < 10; i++) {
      if (x_prevs[i]) {
        x_prevs[i]->next[SOUTH] = NULL;
      }
    }

    house_bits = (1 << now_ind) - 1;
    printf("%d\\n", rec(&map[church_y][church_x], 0));
  }
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

#define EMPTY 0
#define YET_DELIVERED 1
#define CHURCH 2
#define ALREADY_DELIVERED 3

int count;
int house_num;
int map[10][10];
vector<int> x_town[10];
vector<int> y_town[10];

void rec(int x, int y, int depth) {
  int ind_x;
  int ind_y;

  for (ind_y = 0; ind_y < x_town[x].size(); ind_y++) {
    int y2 = x_town[x][ind_y];
    if (y2 == y)
      break;
  }

  for (ind_x = 0; ind_x < y_town[y].size(); ind_x++) {
    int x2 = y_town[y][ind_x];
    if (x2 == x)
      break;
  }

  for (int i = ind_x - 1; i >= 0; i--) {
    int x2 = y_town[y][i];

    if (map[y][x2] == ALREADY_DELIVERED)
      break;

    if (map[y][x2] == CHURCH) {
      if (depth == house_num) {
        count++;
        return;
      }
    }
    if (map[y][x2] == YET_DELIVERED) {
      map[y][x2] = ALREADY_DELIVERED;
      rec(x2, y, depth + 1);
      map[y][x2] = YET_DELIVERED;
    }
  }

  for (int i = ind_x + 1; i < y_town[y].size(); i++) {
    int x2 = y_town[y][i];

    if (map[y][x2] == ALREADY_DELIVERED)
      break;

    if (map[y][x2] == CHURCH) {
      if (depth == house_num) {
        count++;
        return;
      }
    }
    if (map[y][x2] == YET_DELIVERED) {
      map[y][x2] = ALREADY_DELIVERED;
      rec(x2, y, depth + 1);
      map[y][x2] = YET_DELIVERED;
    }
  }

  for (int i = ind_y - 1; i >= 0; i--) {
    int y2 = x_town[x][i];

    if (map[y2][x] == ALREADY_DELIVERED)
      break;

    if (map[y2][x] == CHURCH) {
      if (depth == house_num) {
        count++;
        return;
      }
    }
    if (map[y2][x] == YET_DELIVERED) {
      map[y2][x] = ALREADY_DELIVERED;
      rec(x, y2, depth + 1);
      map[y2][x] = YET_DELIVERED;
    }
  }

  for (int i = ind_y + 1; i < x_town[x].size(); i++) {
    int y2 = x_town[x][i];

    if (map[y2][x] == ALREADY_DELIVERED)
      break;

    if (map[y2][x] == CHURCH) {
      if (depth == house_num) {
        count++;
        return;
      }
    }
    if (map[y2][x] == YET_DELIVERED) {
      map[y2][x] = ALREADY_DELIVERED;
      rec(x, y2, depth + 1);
      map[y2][x] = YET_DELIVERED;
    }
  }

  return;
}

int main() {
  while (1) {
    int m, n;
    int church_x;
    int church_y;

    scanf("%d %d", &m, &n);
    if ((m & n) == 0)
      return 0;

    count = 0;
    house_num = 0;
    memset(map, '\\x00', sizeof(map));
    for (int i = 0; i < 10; i++) {
      x_town[i].clear();
      y_town[i].clear();
    }

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        int p;

        scanf("%d", &p);
        map[i][j] = p;
        x_town[j].push_back(i);
        y_town[i].push_back(j);

        if (p == CHURCH) {
          church_x = j;
          church_y = i;
        } else if (p == YET_DELIVERED) {
          ++house_num;
        }
      }
    }

    rec(church_x, church_y, 0);

    printf("%d\\n", count);
  }
}