Problem p02825 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <chrono>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <ratio>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>

using namespace std;

int n;

using TField = vector<string>;

TField GetField3() { return {"aad", "b.d", "bcc"}; }

TField GetField4() { return {"abee", "abff", "eeab", "ffab"}; }

TField GetField5() { return {"aadaa", "b.dbb", "bccdd", "abd..", "abd.."}; }

TField GetField7() {
  return {"aad...x", "b.d...x", "bcc...y", "...aady",
          "...b.dz", "...bccz", "xxyyzz."};
}

int InferN(const TField &a) {
  int n = a.size();
  for (const auto &s : a) {
    assert(s.size() == n);
  }
  return n;
}

TField CombineOnDiagonal(const TField &lhs, const TField &rhs) {
  int n1 = InferN(lhs);
  int n2 = InferN(rhs);
  int n = n1 + n2;
  TField result(n);
  for (int i = 0; i < n; ++i) {
    result[i].resize(n);
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (i < n1 && j < n1) {
        result[i][j] = lhs[i][j];
      } else if (i >= n1 && j >= n1) {
        result[i][j] = rhs[i][j];
      } else {
        result[i][j] = '.';
      }
    }
  }
  return result;
}

void Show(const TField &a) {
  for (const auto &s : a) {
    cout << s << '\n';
  }
  cout.flush();
}

void Solve() {
  switch (n) {
  case 2: {
    cout << -1 << endl;
    break;
  }
  case 3: {
    Show(GetField3());
    break;
  }
  case 4: {
    Show(GetField4());
    break;
  }
  case 5: {
    Show(GetField5());
    break;
  }
  case 6: {
    Show(CombineOnDiagonal(GetField3(), GetField3()));
    break;
  }
  case 7: {
    Show(GetField7());
    break;
  }
  case 8: {
    Show(CombineOnDiagonal(GetField4(), GetField4()));
    break;
  }
  case 9: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField3(), GetField3()),
                           GetField3()));
    break;
  }
  case 10: {
    Show(CombineOnDiagonal(GetField5(), GetField5()));
    break;
  }
  case 11: {
    Show(CombineOnDiagonal(GetField4(), GetField7()));
    break;
  }
  case 12: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField4(), GetField4()),
                           GetField4()));
    break;
  }
  case 13: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField4(), GetField4()),
                           GetField5()));
    break;
  }
  case 14: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField5(), GetField5()),
                           GetField4()));
    break;
  }
  default: {
    assert(n >= 15);
    bool found = false;
    for (int k = 0; k <= 3; ++k) {
      int r = n - k * 5;
      assert(r >= 0);
      if (r % 4 == 0) {
        found = true;
        TField result;
        for (int i = 0; i < k; ++i) {
          result = CombineOnDiagonal(result, GetField5());
        }
        for (int i = 0; i < r / 4; ++i) {
          result = CombineOnDiagonal(result, GetField4());
        }
        Show(result);
      }
    }
    assert(found);
    break;
  }
  }
}

bool Read() {
  if (!(cin >> n)) {
    return false;
  }
  return true;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);

  while (Read()) {
    Solve();
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <ratio>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>

using namespace std;

int n;

using TField = vector<string>;

TField GetField3() { return {"aad", "b.d", "bcc"}; }

TField GetField4() { return {"abee", "abff", "eeab", "ffab"}; }

TField GetField5() { return {"aadaa", "b.dbb", "bccdd", "abd..", "abd.."}; }

TField GetField7() {
  return {"aad...x", "b.d...x", "bcc...y", "...aady",
          "...b.dz", "...bccz", "xxyyzz."};
}

int InferN(const TField &a) {
  int n = a.size();
  for (const auto &s : a) {
    assert(s.size() == n);
  }
  return n;
}

TField CombineOnDiagonal(const TField &lhs, const TField &rhs) {
  int n1 = InferN(lhs);
  int n2 = InferN(rhs);
  int n = n1 + n2;
  TField result(n);
  for (int i = 0; i < n; ++i) {
    result[i].resize(n);
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (i < n1 && j < n1) {
        result[i][j] = lhs[i][j];
      } else if (i >= n1 && j >= n1) {
        result[i][j] = rhs[i - n1][j - n1];
      } else {
        result[i][j] = '.';
      }
    }
  }
  return result;
}

void Show(const TField &a) {
  for (const auto &s : a) {
    cout << s << '\n';
  }
  cout.flush();
}

void Solve() {
  switch (n) {
  case 2: {
    cout << -1 << endl;
    break;
  }
  case 3: {
    Show(GetField3());
    break;
  }
  case 4: {
    Show(GetField4());
    break;
  }
  case 5: {
    Show(GetField5());
    break;
  }
  case 6: {
    Show(CombineOnDiagonal(GetField3(), GetField3()));
    break;
  }
  case 7: {
    Show(GetField7());
    break;
  }
  case 8: {
    Show(CombineOnDiagonal(GetField4(), GetField4()));
    break;
  }
  case 9: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField3(), GetField3()),
                           GetField3()));
    break;
  }
  case 10: {
    Show(CombineOnDiagonal(GetField5(), GetField5()));
    break;
  }
  case 11: {
    Show(CombineOnDiagonal(GetField4(), GetField7()));
    break;
  }
  case 12: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField4(), GetField4()),
                           GetField4()));
    break;
  }
  case 13: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField4(), GetField4()),
                           GetField5()));
    break;
  }
  case 14: {
    Show(CombineOnDiagonal(CombineOnDiagonal(GetField5(), GetField5()),
                           GetField4()));
    break;
  }
  default: {
    assert(n >= 15);
    bool found = false;
    for (int k = 0; k <= 3; ++k) {
      int r = n - k * 5;
      assert(r >= 0);
      if (r % 4 == 0) {
        found = true;
        TField result;
        for (int i = 0; i < k; ++i) {
          result = CombineOnDiagonal(result, GetField5());
        }
        for (int i = 0; i < r / 4; ++i) {
          result = CombineOnDiagonal(result, GetField4());
        }
        Show(result);
      }
    }
    assert(found);
    break;
  }
  }
}

bool Read() {
  if (!(cin >> n)) {
    return false;
  }
  return true;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);

  while (Read()) {
    Solve();
  }

  return 0;
}