Problem p02745 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)

using namespace std;

constexpr int M = 5000;

bool is_same_char(char a, char b) {
  if (a == '?')
    return true;
  if (b == '?')
    return true;
  return (a == b);
}

void construct(vector<bool> &dst, const string &lhs, const string &rhs) {
  FOR_LT(i, 0, rhs.size()) {
    bool is_ok = true;
    FOR_LT(j, 0, min(lhs.size(), rhs.size() - i)) {
      if (!is_same_char(lhs[j], rhs[j + i])) {
        is_ok = false;
        break;
      }
    }
    dst[M - i] = is_ok;
  }
  FOR_LT(i, 0, lhs.size()) {
    bool is_ok = true;
    FOR_LT(j, 0, min(lhs.size() - i, rhs.size())) {
      if (!is_same_char(lhs[j + i], rhs[j])) {
        is_ok = false;
        break;
      }
    }
    dst[M + i] = is_ok;
  }
}

void print(unordered_map<int, bool> &src) {
  for (auto &s : src) {
    cout << s.first << " " << s.second << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  string a, b, c;
  cin >> a >> b >> c;
  vector<bool> is_ok_ab(M * 2, true);
  vector<bool> is_ok_ac(M * 2, true);
  vector<bool> is_ok_bc(M * 2, true);
  construct(is_ok_ab, a, b);
  construct(is_ok_bc, b, c);
  construct(is_ok_ac, a, c);

  /*
  cout << "ab" << endl;
  print(is_ok_ab);
  cout << "bc" << endl;
  print(is_ok_bc);
  cout << "ca" << endl;
  print(is_ok_ac);
  */

  int ans = INT_MAX;
  FOR_LE(ib, -((int)(b.size() + c.size())), a.size() + c.size()) {
    FOR_LE(ic, -((int)(b.size() + c.size())), a.size() + b.size()) {
      int s = min(min(0, ib), ic);
      int e = max(max((int)a.size(), ib + (int)b.size()), ic + (int)c.size());
      int curans = e - s;
      if (!is_ok_ab[M + ib]) {
        continue;
      }
      if (!is_ok_ac[M + ic]) {
        continue;
      }
      int ibc = ic - ib;
      if (!is_ok_bc[M + ibc]) {
        continue;
      }
      ans = min(ans, curans);
    }
  }
  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)

using namespace std;

constexpr int M = 10000;

bool is_same_char(char a, char b) {
  if (a == '?')
    return true;
  if (b == '?')
    return true;
  return (a == b);
}

void construct(vector<bool> &dst, const string &lhs, const string &rhs) {
  FOR_LT(i, 0, rhs.size()) {
    bool is_ok = true;
    FOR_LT(j, 0, min(lhs.size(), rhs.size() - i)) {
      if (!is_same_char(lhs[j], rhs[j + i])) {
        is_ok = false;
        break;
      }
    }
    dst[M - i] = is_ok;
  }
  FOR_LT(i, 0, lhs.size()) {
    bool is_ok = true;
    FOR_LT(j, 0, min(lhs.size() - i, rhs.size())) {
      if (!is_same_char(lhs[j + i], rhs[j])) {
        is_ok = false;
        break;
      }
    }
    dst[M + i] = is_ok;
  }
}

void print(unordered_map<int, bool> &src) {
  for (auto &s : src) {
    cout << s.first << " " << s.second << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  string a, b, c;
  cin >> a >> b >> c;
  vector<bool> is_ok_ab(M * 2, true);
  vector<bool> is_ok_ac(M * 2, true);
  vector<bool> is_ok_bc(M * 2, true);
  construct(is_ok_ab, a, b);
  construct(is_ok_bc, b, c);
  construct(is_ok_ac, a, c);

  /*
  cout << "ab" << endl;
  print(is_ok_ab);
  cout << "bc" << endl;
  print(is_ok_bc);
  cout << "ca" << endl;
  print(is_ok_ac);
  */

  int ans = INT_MAX;
  FOR_LE(ib, -((int)(b.size() + c.size())), a.size() + c.size()) {
    FOR_LE(ic, -((int)(b.size() + c.size())), a.size() + b.size()) {
      int s = min(min(0, ib), ic);
      int e = max(max((int)a.size(), ib + (int)b.size()), ic + (int)c.size());
      int curans = e - s;
      if (!is_ok_ab[M + ib]) {
        continue;
      }
      if (!is_ok_ac[M + ic]) {
        continue;
      }
      int ibc = ic - ib;
      if (!is_ok_bc[M + ibc]) {
        continue;
      }
      ans = min(ans, curans);
    }
  }
  cout << ans << endl;

  return 0;
}