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

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;

int H, W;
int field[1010][1010];
int ctr[1010][1010];

int count_emp(int x, int y) {
  int c = 0;
  for (int xs = -1; xs <= 1; xs++) {
    for (int ys = -1; ys <= 1; ys++) {
      if (xs == 0 && ys == 0)
        continue;
      if (field[x + xs][y + ys] == 0)
        c++;
    }
  }
  return c;
}
void re_count(int x, int y) {
  field[x][y] = 0;
  for (int xs = -1; xs <= 1; xs++) {
    for (int ys = -1; ys <= 1; ys++) {
      if (xs == 0 && ys == 0)
        continue;
      ctr[x + xs][y + ys]++;
    }
  }
}

int main() {
  cin >> H >> W;
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      char c;
      cin >> c;
      int t = 0;
      if (c != '.')
        t = (int)c - (int)'0';
      field[x][y] = t;
    }
  }

  // count all
  vector<P> updates;
  for (int x = 1; x < W - 1; x++) {
    for (int y = 1; y < H - 1; y++) {
      ctr[x][y] = count_emp(x, y);
      int t = field[x][y];
      if (t > 0 && ctr[x][y] >= t) {
        updates.push_back(P(x, y));
      }
    }
  }

  int ans = 0;
  if (!updates.empty()) {
    // O(N^2 log(N))
    while (true) {
      ans++;
      for (auto p : updates) {
        re_count(p.first, p.second);
      }
      vector<P> tmp;
      for (auto p : updates) {
        for (int xs = -1; xs <= 1; xs++) {
          for (int ys = -1; ys <= 1; ys++) {
            if (xs == 0 && ys == 0)
              continue;
            int x = p.first + xs, y = p.second + ys;
            int t = field[x][y];
            if (t > 0 && ctr[x][y] >= t) {
              if (find(tmp.begin(), tmp.end(), P(x, y)) == tmp.end())
                tmp.push_back(P(x, y));
            }
          }
        }
      }
      updates.clear();
      for (auto p : tmp)
        updates.push_back(p);
      if (updates.empty())
        break;
    }
  }
  cout << ans << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int H, W;
int field[1010][1010];
int ctr[1010][1010];
int ctr_copy[1010][1010];

int count_emp(int x, int y) {
  int c = 0;
  for (int xs = -1; xs <= 1; xs++) {
    for (int ys = -1; ys <= 1; ys++) {
      if (xs == 0 && ys == 0)
        continue;
      if (field[x + xs][y + ys] == 0)
        c++;
    }
  }
  return c;
}
void re_count(int x, int y) {
  for (int xs = -1; xs <= 1; xs++) {
    for (int ys = -1; ys <= 1; ys++) {
      if (xs == 0 && ys == 0)
        continue;
      ctr[x + xs][y + ys]++;
    }
  }
}

int main() {
  cin >> H >> W;
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      char c;
      cin >> c;
      int t = 0;
      if (c != '.')
        t = (int)c - (int)'0';
      field[x][y] = t;
    }
  }

  // count all
  for (int x = 1; x < W - 1; x++) {
    for (int y = 1; y < H - 1; y++) {
      ctr[x][y] = count_emp(x, y);
    }
  }

  int ans = 0;
  while (true) {
    // copy ctr
    for (int x = 1; x < W - 1; x++) {
      for (int y = 1; y < H - 1; y++) {
        ctr_copy[x][y] = ctr[x][y];
      }
    }
    bool changed = false;
    for (int x = 1; x < W - 1; x++) {
      for (int y = 1; y < H - 1; y++) {
        int t = field[x][y];
        if (t > 0 && ctr_copy[x][y] >= t) {
          field[x][y] = 0;
          re_count(x, y);
          changed = true;
        }
      }
    }
    if (!changed)
      break;
    ans += 1;
  }
  cout << ans << "\\n";
  return 0;
}