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

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

const int tx[] = {0, 1, 1, 0};
const int ty[] = {0, 0, 1, 1};

static const double EPS = 1e-10;

struct Point {
  int x;
  int y;
  Point(int _x, int _y) : x(_x), y(_y) {}
  bool operator==(const Point &p) const { return (x == p.x && y == p.y); }
};

int main() {
  int H, W;

  while (~scanf("%d %d", &H, &W)) {
    char stage[500][500];
    map<char, vector<Point>> tiles;
    for (int y = 0; y < H; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (stage[y][x] != '.') {
          tiles[stage[y][x]].push_back(Point(x, y));
        }
      }
    }

    int erased_count = 0;
    bool erased[256];
    memset(erased, false, sizeof(erased));
    erased['.'] = true;

    for (int round = 0; round <= 500 * 500; round++) {

      bool update = false;
      for (int target_char = 'A'; target_char <= 'Z'; target_char++) {
        if (erased[target_char])
          continue;
        if (tiles.find(target_char) == tiles.end())
          continue;

        Point p1(tiles[target_char][0].x, tiles[target_char][0].y);
        Point p2(tiles[target_char][1].x, tiles[target_char][1].y);

        bool isok = true;
        if (p1.x == p2.x) {
          if (abs(p1.y - p2.y) == 1)
            isok = false;

          int x = p1.x;
          for (int y = min(p1.y, p2.y) + 1; y < max(p1.y, p2.y); y++) {
            if (!erased[stage[y][x]]) {
              isok = false;
              break;
            }
          }
        } else if (p1.y == p2.y) {
          if (abs(p1.x - p2.x) == 1)
            isok = false;

          int y = p1.y;
          for (int x = min(p1.x, p2.x) + 1; x < max(p1.x, p2.x); x++) {
            if (!erased[stage[y][x]]) {
              isok = false;
              break;
            }
          }
        } else {

          vector<Point> medium;
          bool can_found = false;
          for (int i = 0; i < tiles[target_char].size(); i++) {
            for (int j = 0; j < tiles[target_char].size(); j++) {
              Point mid(tiles[target_char][i].x, tiles[target_char][j].y);

              if (mid == p1 || mid == p2)
                continue;
              if (!erased[stage[mid.y][mid.x]])
                continue;

              // target p1.x,p1.y
              int flag1 = 0;
              for (int x = min(mid.x, p1.x); x <= max(mid.x, p1.x); x++) {
                if (Point(x, p1.y) == p1)
                  continue;
                if (!erased[stage[mid.y][x]])
                  flag1 |= 1;
              }

              for (int y = min(mid.y, p1.y); y <= max(mid.y, p1.y); y++) {
                if (Point(p1.x, y) == p1)
                  continue;
                if (!erased[stage[y][mid.x]])
                  flag1 |= (1 << 1);
              }

              // target x2,y2
              int flag2 = 0;
              for (int x = min(mid.x, p2.x); x <= max(mid.x, p2.x); x++) {
                if (Point(x, p2.y) == p2)
                  continue;
                if (!erased[stage[mid.y][x]])
                  flag2 |= 1;
              }

              for (int y = min(mid.y, p2.y); y <= max(mid.y, p2.y); y++) {
                if (Point(p2.x, y) == p2)
                  continue;
                if (!erased[stage[y][mid.x]])
                  flag2 |= (1 << 1);
              }

              if (flag1 == 0 && flag2 == 0) {
                can_found = true;
              }
            }
          }

          if (!can_found) {
            isok = false;
          }
        }
        if (isok) {
          update = true;
          erased[target_char] = true;
          erased_count++;
        }
      }

      if (!update)
        break;
    }
    printf("%d\\n", erased_count * 2);
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

const int tx[] = {0, 1, 1, 0};
const int ty[] = {0, 0, 1, 1};

static const double EPS = 1e-10;

struct Point {
  int x;
  int y;
  Point(int _x, int _y) : x(_x), y(_y) {}
  bool operator==(const Point &p) const { return (x == p.x && y == p.y); }
};

int main() {
  int H, W;

  while (~scanf("%d %d", &H, &W)) {
    char stage[500][500];
    map<char, vector<Point>> tiles;
    for (int y = 0; y < H; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (stage[y][x] != '.') {
          tiles[stage[y][x]].push_back(Point(x, y));
        }
      }
    }

    int erased_count = 0;
    bool erased[256];
    memset(erased, false, sizeof(erased));
    erased['.'] = true;

    for (int round = 0; round <= 500 * 500; round++) {
      for (int target_char = 'A'; target_char <= 'Z'; target_char++) {
        if (erased[target_char])
          continue;
        if (tiles.find(target_char) == tiles.end())
          continue;

        Point p1(tiles[target_char][0].x, tiles[target_char][0].y);
        Point p2(tiles[target_char][1].x, tiles[target_char][1].y);

        bool isok = true;
        if (p1.x == p2.x) {
          if (abs(p1.y - p2.y) == 1)
            isok = false;

          int x = p1.x;
          for (int y = min(p1.y, p2.y) + 1; y < max(p1.y, p2.y); y++) {
            if (!erased[stage[y][x]]) {
              isok = false;
              break;
            }
          }
        } else if (p1.y == p2.y) {
          if (abs(p1.x - p2.x) == 1)
            isok = false;

          int y = p1.y;
          for (int x = min(p1.x, p2.x) + 1; x < max(p1.x, p2.x); x++) {
            if (!erased[stage[y][x]]) {
              isok = false;
              break;
            }
          }
        } else {

          vector<Point> medium;
          bool can_found = false;
          for (int i = 0; i < tiles[target_char].size(); i++) {
            for (int j = 0; j < tiles[target_char].size(); j++) {
              Point mid(tiles[target_char][i].x, tiles[target_char][j].y);

              if (mid == p1 || mid == p2)
                continue;
              if (!erased[stage[mid.y][mid.x]])
                continue;

              // target p1.x,p1.y
              int flag1 = 0;
              for (int x = min(mid.x, p1.x); x <= max(mid.x, p1.x); x++) {
                if (Point(x, p1.y) == p1)
                  continue;
                if (!erased[stage[mid.y][x]])
                  flag1 |= 1;
              }

              for (int y = min(mid.y, p1.y); y <= max(mid.y, p1.y); y++) {
                if (Point(p1.x, y) == p1)
                  continue;
                if (!erased[stage[y][mid.x]])
                  flag1 |= (1 << 1);
              }

              // target x2,y2
              int flag2 = 0;
              for (int x = min(mid.x, p2.x); x <= max(mid.x, p2.x); x++) {
                if (Point(x, p2.y) == p2)
                  continue;
                if (!erased[stage[mid.y][x]])
                  flag2 |= 1;
              }

              for (int y = min(mid.y, p2.y); y <= max(mid.y, p2.y); y++) {
                if (Point(p2.x, y) == p2)
                  continue;
                if (!erased[stage[y][mid.x]])
                  flag2 |= (1 << 1);
              }

              if (flag1 == 0 && flag2 == 0) {
                can_found = true;
              }
            }
          }

          if (!can_found) {
            isok = false;
          }
        }
        if (isok) {
          erased[target_char] = true;
          erased_count++;
        }
      }
    }
    printf("%d\\n", erased_count * 2);
  }
}