Problem p02745 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

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

const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};

// Self settings
// clang-format off
#define MAX_N 100000
#define MAX 100000
#define INFTY (1<<30)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define REP(i, N) for (int i = 0; i < (int)(N); ++i)
#define SLN(i,N) (i == N-1 ? "\n" : " ")
ll fact(ll n) { ll res = 1; for(ll i=2;i<=n;++i) res = res * i; return res;}
ll nCr(ll n, ll r) {return (fact(n)/fact(n-r)*fact(r)) ;}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const ll MOD = 1e9+7;
const ll INF = 1LL << 60;
const int inf = 1000100011;
class Point { public: double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} Point operator+(Point p) { return Point(x + p.x, y + p.y); } Point operator-(Point p) { return Point(x - p.x, y - p.y); } Point operator*(double a) { return Point(a * x, a * y); } Point operator/(double a) { return Point(x / a, y / a); } double abs() { return sqrt(norm()); } double norm() { return x * x + y * y; } bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; } bool operator==(const Point& p) const { return fabs(x - p.y) < EPS && fabs(y - p.y) < EPS; } };
typedef Point Vector;
double norm(Vector a) { return a.x * a.x + a.y * a.y; }
double abs(Vector a) { return sqrt(norm(a));}
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
struct Segment { Point p1, p2; };
typedef Segment Line;
// clang-format on

#define M 2000

bool ab[10000], ac[100000], bc[100000];

bool match(char c1, char c2) { return (c1 == '?' || c2 == '?' || c1 == c2); }

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string a, b, c;
  cin >> a >> b >> c;

  int A = a.length();
  int B = b.length();
  int C = c.length();

  REP(i, A) REP(j, B) if (!match(a[i], b[j])) ab[i - j + 50000] = true;
  REP(i, A) REP(j, C) if (!match(a[i], c[j])) ac[i - j + 50000] = true;
  REP(i, B) REP(j, C) if (!match(b[i], c[j])) bc[i - j + 50000] = true;

  int ans = 3 * M;
  for (int i = -2 * M; i <= 2 * M; i++) {
    for (int j = -2 * M; j <= 2 * M; j++) {
      if (!ab[i + 50000] && !ac[j + 50000] && !bc[j - i + 50000]) {
        int L = min(0, min(i, j));
        int R = max(A, max(B + i, C + j));
        ans = min(ans, R - L);
      }
    }
  }
  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

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

const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};

// Self settings
// clang-format off
#define MAX_N 100000
#define MAX 100000
#define INFTY (1<<30)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define REP(i, N) for (int i = 0; i < (int)(N); ++i)
#define SLN(i,N) (i == N-1 ? "\n" : " ")
ll fact(ll n) { ll res = 1; for(ll i=2;i<=n;++i) res = res * i; return res;}
ll nCr(ll n, ll r) {return (fact(n)/fact(n-r)*fact(r)) ;}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const ll MOD = 1e9+7;
const ll INF = 1LL << 60;
const int inf = 1000100011;
class Point { public: double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} Point operator+(Point p) { return Point(x + p.x, y + p.y); } Point operator-(Point p) { return Point(x - p.x, y - p.y); } Point operator*(double a) { return Point(a * x, a * y); } Point operator/(double a) { return Point(x / a, y / a); } double abs() { return sqrt(norm()); } double norm() { return x * x + y * y; } bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; } bool operator==(const Point& p) const { return fabs(x - p.y) < EPS && fabs(y - p.y) < EPS; } };
typedef Point Vector;
double norm(Vector a) { return a.x * a.x + a.y * a.y; }
double abs(Vector a) { return sqrt(norm(a));}
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
struct Segment { Point p1, p2; };
typedef Segment Line;
// clang-format on

#define M 2000

bool ab[100000], ac[100000], bc[100000];

bool match(char c1, char c2) { return (c1 == '?' || c2 == '?' || c1 == c2); }

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string a, b, c;
  cin >> a >> b >> c;

  int A = a.length();
  int B = b.length();
  int C = c.length();

  REP(i, A) REP(j, B) if (!match(a[i], b[j])) ab[i - j + 50000] = true;
  REP(i, A) REP(j, C) if (!match(a[i], c[j])) ac[i - j + 50000] = true;
  REP(i, B) REP(j, C) if (!match(b[i], c[j])) bc[i - j + 50000] = true;

  int ans = 3 * M;
  for (int i = -2 * M; i <= 2 * M; i++) {
    for (int j = -2 * M; j <= 2 * M; j++) {
      if (!ab[i + 50000] && !ac[j + 50000] && !bc[j - i + 50000]) {
        int L = min(0, min(i, j));
        int R = max(A, max(B + i, C + j));
        ans = min(ans, R - L);
      }
    }
  }
  cout << ans << endl;

  return 0;
}