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

#include <cstring>
#include <iostream>
#include <stack>
using namespace std;

#define N 10
struct point {
  int x, y, size;
};

int n;
int total_drop = 0;
int cloth[N][N];
int smallx[4] = {1, -1, 0, 0};
int smally[4] = {0, 0, 1, -1};
int midx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int midy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
int bigx[12] = {-2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 2};
int bigy[12] = {0, -1, 0, 1, -2, -1, 1, 2, -1, 0, 1, 0};
stack<point> st;

bool can_drop_big(int x, int y) {
  for (int i = 0; i < 12; i++) {
    int mx = x + bigx[i];
    int my = y + bigy[i];
    if (mx < 0 || mx >= N || my < 0 || my >= N) {
      return false;
    }
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

bool can_drop_mid(int x, int y) {
  for (int i = 0; i < 8; i++) {
    int mx = x + midx[i];
    int my = y + midy[i];
    if (mx < 0 || mx >= N || my < 0 || my >= N) {
      return false;
    }
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

bool can_drop_small(int x, int y) {
  for (int i = 0; i < 4; i++) {
    int mx = x + smallx[i];
    int my = y + smally[i];
    if (mx < 0 || mx >= N || my < 0 || my >= N) {
      return false;
    }
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

void del_big(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 12; i++) {
    int mx = x + bigx[i];
    int my = y + bigy[i];
    cloth[my][mx]--;
  }
}

void del_mid(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 8; i++) {
    int mx = x + midx[i];
    int my = y + midy[i];
    cloth[my][mx]--;
  }
}

void del_small(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 4; i++) {
    int mx = x + smallx[i];
    int my = y + smally[i];
    cloth[my][mx]--;
  }
}

bool dfs(int y, int x, int drop_num) {
  if (drop_num < 0) {
    return false;
  }
  if (y == N) {
    return drop_num == 0;
  }
  if (cloth[y][x] == 0) {
    return dfs(y + (x == 9), (x + 1) % N, drop_num);
  }
  int cloth_cp[N][N];
  if (can_drop_small(x, y + 1)) {
    memcpy(cloth_cp, cloth, sizeof(cloth));
    del_small(x, y + 1);
    if (dfs(y, x, drop_num - 1)) {
      cout << x << " " << y + 1 << " " << 1 << endl;
      return true;
    }
    memcpy(cloth, cloth_cp, sizeof(cloth));
  }
  if (can_drop_mid(x + 1, y + 1)) {
    memcpy(cloth_cp, cloth, sizeof(cloth));
    del_mid(x + 1, y + 1);
    if (dfs(y, x, drop_num - 1)) {
      cout << x + 1 << " " << y + 1 << " " << 2 << endl;
      return true;
    }
    memcpy(cloth, cloth_cp, sizeof(cloth));
  }
  if (can_drop_big(x, y + 2)) {
    memcpy(cloth_cp, cloth, sizeof(cloth));
    del_big(x, y + 2);
    if (dfs(y, x, drop_num - 1)) {
      cout << x << " " << y + 2 << " " << 3 << endl;
      return true;
    }
    memcpy(cloth, cloth_cp, sizeof(cloth));
  }

  return false;
}

int main() {
  cin >> n;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cin >> cloth[i][j];
    }
  }
  dfs(0, 0, n);
  return 0;
}

Error: TLE

Fixed submission:

#include <cstring>
#include <iostream>
#include <stack>
using namespace std;

#define N 10
struct point {
  int x, y, size;
};

int n;
int total_drop = 0;
int cloth[N][N];
int smallx[4] = {1, -1, 0, 0};
int smally[4] = {0, 0, 1, -1};
int midx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int midy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
int bigx[12] = {-2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 2};
int bigy[12] = {0, -1, 0, 1, -2, -1, 1, 2, -1, 0, 1, 0};
stack<point> st;

bool can_drop_big(int x, int y) {
  for (int i = 0; i < 12; i++) {
    int mx = x + bigx[i];
    int my = y + bigy[i];
    if (mx < 0 || mx >= N || my < 0 || my >= N) {
      return false;
    }
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

bool can_drop_mid(int x, int y) {
  for (int i = 0; i < 8; i++) {
    int mx = x + midx[i];
    int my = y + midy[i];
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

bool can_drop_small(int x, int y) {
  for (int i = 0; i < 4; i++) {
    int mx = x + smallx[i];
    int my = y + smally[i];
    if (cloth[my][mx] == 0) {
      return false;
    }
  }
  return true;
}

void del_big(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 12; i++) {
    int mx = x + bigx[i];
    int my = y + bigy[i];
    cloth[my][mx]--;
  }
}

void del_mid(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 8; i++) {
    int mx = x + midx[i];
    int my = y + midy[i];
    cloth[my][mx]--;
  }
}

void del_small(int x, int y) {
  cloth[y][x]--;
  for (int i = 0; i < 4; i++) {
    int mx = x + smallx[i];
    int my = y + smally[i];
    cloth[my][mx]--;
  }
}

void dfs(int drop_num, int ink_num) {
  if (drop_num == n) {
    if (ink_num == total_drop) {
      while (!st.empty()) {
        point p = st.top();
        cout << p.x << " " << p.y << " " << p.size << endl;
        st.pop();
      }
    }
    return;
  }
  int cloth_cp[N][N];
  for (int y = 1; y < N - 1; y++) {
    for (int x = 1; x < N - 1; x++) {
      if (cloth[y][x] == 0) {
        continue;
      }

      if (can_drop_small(x, y)) {
        memcpy(cloth_cp, cloth, sizeof(cloth));
        del_small(x, y);
        st.push(point({x, y, 1}));
        dfs(drop_num + 1, ink_num + 5);
        if (st.empty()) {
          return;
        }
        st.pop();
        memcpy(cloth, cloth_cp, sizeof(cloth));
      } else {
        continue;
      }
      if (can_drop_mid(x, y)) {
        memcpy(cloth_cp, cloth, sizeof(cloth));
        del_mid(x, y);
        st.push(point({x, y, 2}));
        dfs(drop_num + 1, ink_num + 9);
        if (st.empty()) {
          return;
        }
        st.pop();
        memcpy(cloth, cloth_cp, sizeof(cloth));
      } else {
        continue;
      }
      if (can_drop_big(x, y)) {
        memcpy(cloth_cp, cloth, sizeof(cloth));
        del_big(x, y);
        st.push(point({x, y, 3}));
        dfs(drop_num + 1, ink_num + 13);
        if (st.empty()) {
          return;
        }
        st.pop();
        memcpy(cloth, cloth_cp, sizeof(cloth));
      }
    }
  }
}

int get_drop_ink_num() {
  int count = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (cloth[i][j] >= 0) {
        count += cloth[i][j];
      }
    }
  }
  return count;
}

int main() {
  cin >> n;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cin >> cloth[i][j];
    }
  }
  total_drop = get_drop_ink_num();
  dfs(0, 0);
  return 0;
}