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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

const int H = 10, W = 10;

inline bool change_cell(vvi &grid, int i, int j, int x) {
  if (i < 0 || H <= i || j < 0 || W <= j)
    return true;
  if (grid[i][j] + x < 0)
    return false;
  grid[i][j] += x;
  return true;
}
inline bool change_large(vvi &grid, int ci, int cj, int x) {
  if (ci < 2 || H - 2 <= ci || cj < 2 || W - 2 <= cj)
    return false;
  const int di[] = {-2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2};
  const int dj[] = {0, -1, 0, 1, -2, -1, 0, 1, 2, -1, 0, 1, 0};
  rep(i, 13) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
inline bool change_medium(vvi &grid, int ci, int cj, int x) {
  if (ci < 1 || H - 1 <= ci || cj < 1 || W - 1 <= cj)
    return false;
  const int di[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};
  const int dj[] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
  rep(i, 9) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
inline bool change_small(vvi &grid, int ci, int cj, int x) {
  if (ci < 1 || H - 1 <= ci || cj < 1 || W - 1 <= cj)
    return false;
  const int di[] = {-1, 0, 0, 0, 1};
  const int dj[] = {0, -1, 0, 1, 0};
  rep(i, 5) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
// 拭き取る
inline bool wipe_large(vvi &grid, int ci, int cj) {
  return change_large(grid, ci, cj, -1);
}
inline bool wipe_medium(vvi &grid, int ci, int cj) {
  return change_medium(grid, ci, cj, -1);
}
inline bool wipe_small(vvi &grid, int ci, int cj) {
  return change_small(grid, ci, cj, -1);
}
// 染める
inline bool dip_large(vvi &grid, int ci, int cj) {
  return change_large(grid, ci, cj, 1);
}
inline bool dip_medium(vvi &grid, int ci, int cj) {
  return change_medium(grid, ci, cj, 1);
}
inline bool dip_small(vvi &grid, int ci, int cj) {
  return change_small(grid, ci, cj, 1);
}

inline bool solve(vvi &grid, int cur, int rest, vector<pair<pii, int>> &dips) {
  if (rest == 0) {
    rep(i, H) rep(j, W) if (grid[i][j]) return false;
    return true;
  }

  // 枝刈り
  // rep(i,H) rep(j,W) if(grid[i][j]){
  //	int cnt=0;
  //	rep(k,4){
  //		int ii=i+"\\xff\\x1\\0\\0"[k],jj=j+"\\0\\0\\xff\\x1"[k];
  //		cnt+=0<=ii&&ii<H&&0<=jj&&jj<W&&grid[ii][jj];
  //	}
  //	if(!cnt) return false;
  //}
  rep(i, cur / W - 2) rep(j, W) if (grid[i][j]) return false;

  repi(k, cur, H * W) {
    int i = k / W, j = k % W;
    if (!grid[i][j])
      continue;
    // if(!wipe_small(grid,i,j)) continue;
    // dip_small(grid,i,j);

    if (wipe_large(grid, i, j)) {
      dips.emplace_back(mp(i, j), 3);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_large(grid, i, j);
      dips.pop_back();
    }
    if (wipe_medium(grid, i, j)) {
      dips.emplace_back(mp(i, j), 2);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_medium(grid, i, j);
      dips.pop_back();
    }
    if (wipe_small(grid, i, j)) {
      dips.emplace_back(mp(i, j), 1);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_small(grid, i, j);
      dips.pop_back();
    }
  }
  return false;
}

#include <sys/time.h>
double myclock() {
  timeval t;
  gettimeofday(&t, 0);
  return t.tv_sec + 1e-6 * t.tv_usec;
}

int main() {
  for (int n; cin >> n && n;) {
    vvi grid(H, vi(W));
    rep(i, H) rep(j, W) cin >> grid[i][j];

    double begin = myclock();
    vector<pair<pii, int>> dips;
    assert(solve(grid, 0, n, dips));
    double end = myclock();

    for (auto d : dips)
      printf("%d %d %d\\n", d.first.second, d.first.first, d.second);
    // printf("%.3f[s]\\n",end-begin);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

const int H = 10, W = 10;

inline bool change_cell(vvi &grid, int i, int j, int x) {
  if (i < 0 || H <= i || j < 0 || W <= j)
    return true;
  if (grid[i][j] + x < 0)
    return false;
  grid[i][j] += x;
  return true;
}
inline bool change_large(vvi &grid, int ci, int cj, int x) {
  if (ci < 2 || H - 2 <= ci || cj < 2 || W - 2 <= cj)
    return false;
  const int di[] = {-2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2};
  const int dj[] = {0, -1, 0, 1, -2, -1, 0, 1, 2, -1, 0, 1, 0};
  rep(i, 13) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
inline bool change_medium(vvi &grid, int ci, int cj, int x) {
  if (ci < 1 || H - 1 <= ci || cj < 1 || W - 1 <= cj)
    return false;
  const int di[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};
  const int dj[] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
  rep(i, 9) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
inline bool change_small(vvi &grid, int ci, int cj, int x) {
  if (ci < 1 || H - 1 <= ci || cj < 1 || W - 1 <= cj)
    return false;
  const int di[] = {-1, 0, 0, 0, 1};
  const int dj[] = {0, -1, 0, 1, 0};
  rep(i, 5) if (!change_cell(grid, ci + di[i], cj + dj[i], x)) {
    rep(j, i) change_cell(grid, ci + di[j], cj + dj[j], -x);
    return false;
  }
  return true;
}
// 拭き取る
inline bool wipe_large(vvi &grid, int ci, int cj) {
  return change_large(grid, ci, cj, -1);
}
inline bool wipe_medium(vvi &grid, int ci, int cj) {
  return change_medium(grid, ci, cj, -1);
}
inline bool wipe_small(vvi &grid, int ci, int cj) {
  return change_small(grid, ci, cj, -1);
}
// 染める
inline bool dip_large(vvi &grid, int ci, int cj) {
  return change_large(grid, ci, cj, 1);
}
inline bool dip_medium(vvi &grid, int ci, int cj) {
  return change_medium(grid, ci, cj, 1);
}
inline bool dip_small(vvi &grid, int ci, int cj) {
  return change_small(grid, ci, cj, 1);
}

inline bool solve(vvi &grid, int cur, int rest, vector<pair<pii, int>> &dips) {
  if (rest == 0) {
    rep(i, H) rep(j, W) if (grid[i][j]) return false;
    return true;
  }

  // 枝刈り
  rep(i, H) rep(j, W) if (grid[i][j]) {
    int cnt = 0;
    rep(k, 4) {
      int ii = i + "\\xff\\x1\\0\\0"[k], jj = j + "\\0\\0\\xff\\x1"[k];
      cnt += 0 <= ii && ii < H && 0 <= jj && jj < W && grid[ii][jj];
    }
    if (!cnt)
      return false;
  }
  rep(i, cur / W - 2) rep(j, W) if (grid[i][j]) return false;

  repi(k, cur, H * W) {
    int i = k / W, j = k % W;
    if (!grid[i][j])
      continue;
    if (!wipe_small(grid, i, j))
      continue;
    dip_small(grid, i, j);

    if (wipe_large(grid, i, j)) {
      dips.emplace_back(mp(i, j), 3);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_large(grid, i, j);
      dips.pop_back();
    }
    if (wipe_medium(grid, i, j)) {
      dips.emplace_back(mp(i, j), 2);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_medium(grid, i, j);
      dips.pop_back();
    }
    if (wipe_small(grid, i, j)) {
      dips.emplace_back(mp(i, j), 1);
      if (solve(grid, k, rest - 1, dips))
        return true;
      dip_small(grid, i, j);
      dips.pop_back();
    }
  }
  return false;
}

#include <sys/time.h>
double myclock() {
  timeval t;
  gettimeofday(&t, 0);
  return t.tv_sec + 1e-6 * t.tv_usec;
}

int main() {
  for (int n; cin >> n && n;) {
    vvi grid(H, vi(W));
    rep(i, H) rep(j, W) cin >> grid[i][j];

    double begin = myclock();
    vector<pair<pii, int>> dips;
    assert(solve(grid, 0, n, dips));
    double end = myclock();

    for (auto d : dips)
      printf("%d %d %d\\n", d.first.second, d.first.first, d.second);
    // printf("%.3f[s]\\n",end-begin);
  }

  return 0;
}