Problem p01236 (C++)

Buggy submission (status: Time Limit Exceeded):
#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;

int H, W;

vector<pair<int, int>> get_z(int now_x, int now_y) {
  int rest = W + 1;
  vector<pair<int, int>> z;
  while (rest--) {
    if (!now_x && !now_y)
      break;
    if (!now_x) {
      now_y--;
      now_x = W - 1;
    } else {
      now_x--;
    }
    z.push_back(make_pair(now_x, now_y));
  }
  reverse(z.begin(), z.end());
  return z;
}

bool connect(pair<int, int> &l, pair<int, int> &r) {
  return abs(l.first - r.first) <= 1 && abs(l.second - r.second) <= 1;
}

int main() {
  int case_cnt = 0;
  while (cin >> W >> H) {
    if (!H)
      break;
    case_cnt++;
    vector<vector<int>> field(H, vector<int>(W));
    for (int i = 0; i < H; ++i) {
      string st;
      cin >> st;
      for (int j = 0; j < W; ++j) {
        field[i][j] = st[j] == '#';
      }
    }

    map<vector<pair<int, int>>, pair<int, int>> prevs;
    prevs.emplace(vector<pair<int, int>>(0), make_pair(0, 0));

    int dx8[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
    int dy8[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
    for (int now_y = 0; now_y < H; ++now_y) {
      for (int now_x = 0; now_x < W; ++now_x) {
        pair<int, int> now(now_x, now_y);
        map<vector<pair<int, int>>, pair<int, int>> next_prevs;
        vector<pair<int, int>> zahyous(get_z(now_x, now_y));
        for (auto &&aprev : prevs) {
          const int prev_min_cnt = aprev.second.first;
          const int prev_max_cnt = aprev.second.second;
          for (int now_black = 0; now_black < 2; ++now_black) {
            vector<pair<int, int>> next_p(aprev.first);
            // black

            int now_num = now_black;
            {
              bool x_hasi = now_x == 0 || now_x == W - 1;
              bool y_hasi = now_y == 0 || now_y == H - 1;
              if (x_hasi && y_hasi) {
                if (H == 1 || W == 1)
                  now_num *= 6;
                else
                  now_num *= 4;
              } else if (x_hasi || y_hasi) {

                if (x_hasi && now_x == 0 && now_x == W - 1)
                  now_num *= 3;
                else if (y_hasi && now_y == 0 && now_y == H - 1)
                  now_num *= 3;
                else
                  now_num *= 2;
              }
            }
            for (int i = 0; i < zahyous.size(); ++i) {

              int bai = 1;
              if (now_x == 0 && zahyous[i].first == 0)
                bai++;
              if (now_x == W - 1 && zahyous[i].first == W - 1)
                bai++;
              if (now_y == 0 && zahyous[i].second == 0)
                bai++;
              if (now_y == H - 1 && zahyous[i].second == H - 1)
                bai++;
              if (connect(zahyous[i], now)) {
                if (now_black) {
                  next_p[i].second += bai;
                }
                if (next_p[i].first) {
                  now_num += bai;
                }
              }
            }

            bool ok = true;
            if (zahyous.size() == W + 1) {
              bool f_black = field[zahyous[0].second][zahyous[0].first] == 1;
              int num = next_p[0].second;
              if ((f_black ^ (num >= 5))) {
                ok = false;
              }
            }

            if (ok) {

              if (zahyous.size() == W + 1) {
                next_p.erase(next_p.begin());
              }
              next_p.push_back(make_pair(now_black, now_num));
              for (int i = 0; i < next_p.size(); ++i) {
                next_p[i].second = min(5, next_p[i].second);
              }
              if (next_prevs.find(next_p) == next_prevs.end()) {
                next_prevs[next_p] = make_pair(prev_min_cnt + now_black,
                                               prev_max_cnt + now_black);
              } else {
                next_prevs[next_p] = make_pair(
                    min(next_prevs[next_p].first, prev_min_cnt + now_black),
                    max(next_prevs[next_p].second, prev_max_cnt + now_black));
              }
            }
          }
        }
        prevs = move(next_prevs);
        next_prevs.clear();
      }
    }
    int amin = 1000;
    int amax = -1;
    {
      vector<pair<int, int>> zahyous(get_z(0, H));
      for (auto &&pr : prevs) {
        bool valid = true;
        for (int i = 0; i < pr.first.size(); ++i) {
          bool f_black = field[zahyous[i].second][zahyous[i].first] == 1;
          int num = pr.first[i].second;
          if (f_black ^ (num >= 5)) {
            valid = false;
          }
        }
        if (valid) {
          amin = min(amin, pr.second.first);
          amax = max(amax, pr.second.second);
        }
      }
    }

    cout << "Case " << case_cnt << ": ";
    if (amin == 1000) {
      cout << "Impossible" << endl;
    } else {
      cout << amax - amin << endl;
    }
  }
  return 0;
}


Fixed submission:
#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;

int H, W;

vector<pair<int, int>> get_z(int now_x, int now_y) {
  int rest = W + 1;
  vector<pair<int, int>> z;
  while (rest--) {
    if (!now_x && !now_y)
      break;
    if (!now_x) {
      now_y--;
      now_x = W - 1;
    } else {
      now_x--;
    }
    z.push_back(make_pair(now_x, now_y));
  }
  reverse(z.begin(), z.end());
  return z;
}

bool connect(pair<int, int> &l, pair<int, int> &r) {
  return abs(l.first - r.first) <= 1 && abs(l.second - r.second) <= 1;
}

int main() {
  int case_cnt = 0;
  while (cin >> W >> H) {
    if (!H)
      break;
    case_cnt++;
    vector<vector<int>> field(H, vector<int>(W));
    for (int i = 0; i < H; ++i) {
      string st;
      cin >> st;
      for (int j = 0; j < W; ++j) {
        field[i][j] = st[j] == '#';
      }
    }

    map<vector<pair<int, int>>, pair<int, int>> prevs;
    prevs.emplace(vector<pair<int, int>>(0), make_pair(0, 0));

    int dx8[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
    int dy8[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
    for (int now_y = 0; now_y < H; ++now_y) {
      for (int now_x = 0; now_x < W; ++now_x) {
        pair<int, int> now(now_x, now_y);
        map<vector<pair<int, int>>, pair<int, int>> next_prevs;
        vector<pair<int, int>> zahyous(get_z(now_x, now_y));
        for (auto &&aprev : prevs) {
          const int prev_min_cnt = aprev.second.first;
          const int prev_max_cnt = aprev.second.second;
          for (int now_black = 0; now_black < 2; ++now_black) {
            vector<pair<int, int>> next_p(aprev.first);
            // black

            int now_num = now_black;
            {
              bool x_hasi = now_x == 0 || now_x == W - 1;
              bool y_hasi = now_y == 0 || now_y == H - 1;
              if (x_hasi && y_hasi) {
                if (H == 1 || W == 1)
                  now_num *= 6;
                else
                  now_num *= 4;
              } else if (x_hasi || y_hasi) {

                if (x_hasi && now_x == 0 && now_x == W - 1)
                  now_num *= 3;
                else if (y_hasi && now_y == 0 && now_y == H - 1)
                  now_num *= 3;
                else
                  now_num *= 2;
              }
            }
            for (int i = 0; i < zahyous.size(); ++i) {

              int bai = 1;
              if (now_x == 0 && zahyous[i].first == 0)
                bai++;
              if (now_x == W - 1 && zahyous[i].first == W - 1)
                bai++;
              if (now_y == 0 && zahyous[i].second == 0)
                bai++;
              if (now_y == H - 1 && zahyous[i].second == H - 1)
                bai++;
              if (connect(zahyous[i], now)) {
                if (now_black) {
                  next_p[i].second += bai;
                }
                if (next_p[i].first) {
                  now_num += bai;
                }
              }
            }

            bool ok = true;
            if (zahyous.size() == W + 1) {
              bool f_black = field[zahyous[0].second][zahyous[0].first] == 1;
              int num = next_p[0].second;
              if ((f_black ^ (num >= 5))) {
                ok = false;
              }
            }

            if (ok) {

              if (zahyous.size() == W + 1) {
                next_p.erase(next_p.begin());
              }
              next_p.push_back(make_pair(now_black, now_num));
              for (int i = 0; i < next_p.size(); ++i) {
                next_p[i].second = min(5, next_p[i].second);
              }
              if (next_p.size() == W + 1 && next_p[0].second < 3)
                next_p[0].second = 0;
              if (next_prevs.find(next_p) == next_prevs.end()) {
                next_prevs[next_p] = make_pair(prev_min_cnt + now_black,
                                               prev_max_cnt + now_black);
              } else {
                next_prevs[next_p] = make_pair(
                    min(next_prevs[next_p].first, prev_min_cnt + now_black),
                    max(next_prevs[next_p].second, prev_max_cnt + now_black));
              }
            }
          }
        }
        prevs = move(next_prevs);
        next_prevs.clear();
      }
    }
    int amin = 1000;
    int amax = -1;
    {
      vector<pair<int, int>> zahyous(get_z(0, H));
      for (auto &&pr : prevs) {
        bool valid = true;
        for (int i = 0; i < pr.first.size(); ++i) {
          bool f_black = field[zahyous[i].second][zahyous[i].first] == 1;
          int num = pr.first[i].second;
          if (f_black ^ (num >= 5)) {
            valid = false;
          }
        }
        if (valid) {
          amin = min(amin, pr.second.first);
          amax = max(amax, pr.second.second);
        }
      }
    }

    cout << "Case " << case_cnt << ": ";
    if (amin == 1000) {
      cout << "Impossible" << endl;
    } else {
      cout << amax - amin << endl;
    }
  }
  return 0;
}