Problem p02697 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define rep(i, n) for (i = 0; i < n; i++)
using namespace std;

int n, m;

bool check1(vector<int> a, vector<int> b) {
  int i;
  vector<bool> exist(n + 1, false);
  rep(i, m) {
    if (a[i] <= 0 || a[i] > n)
      return false;
    if (b[i] <= 0 || b[i] > n)
      return false;
    if (exist[a[i]])
      return false;
    exist[a[i]] = true;
    if (exist[b[i]])
      return false;
    exist[b[i]] = true;
  }
  return true;
}

bool check2(vector<int> a, vector<int> b) {
  int i;

  vector<bool> used(n + 1, false);
  rep(i, m) {
    int x = abs(a[i] - b[i]);
    x = min(n - x, x);
    if (n % 2 == 0 && x == n / 2)
      return false;
    if (used[x]) {
      cout << "a, b = " << a[i] << ", " << b[i] << ", x = " << x << endl;
      return false;
    }
    used[x] = true;
  }
  return true;
}

void debug2(vector<int> a, vector<int> b) {
  int i;
  rep(i, m) {
    int x = abs(a[i] - b[i]);
    x = min(n - x, x);
    cout << "a, b = " << a[i] << ", " << b[i] << ", x = " << x << endl;
  }
}

bool naive_checker(vector<int> a, vector<int> b) {
  if (check1(a, b) == false)
    return false;
  if ((int)a.size() != m || (int)b.size() != m) {
    return false;
  }

  typedef pair<int, int> P;
  set<P> appear;

  int i, j;
  for (i = 0; i < n; i++) {
    cerr << endl;
    for (j = 0; j < m; j++) {
      int A = a[j] - i;
      if (A <= 0)
        A += n;
      int B = b[j] - i;
      if (B <= 0)
        B += n;
      cerr << A << ", " << B << endl;
      if (appear.find(P(A, B)) != appear.end() ||
          appear.find(P(B, A)) != appear.end())
        return false;
      appear.insert(P(A, B));
      appear.insert(P(B, A));
    }
  }
  return true;
}

vector<int> a;
vector<int> b;
void solve() {
  if (n % 2 == 1) {
    for (int i = 0; i < m; i++) {
      a.push_back(i + 1);
      b.push_back(n - i);
    }
  } else {
    int x = 1;
    int y = n;
    for (int i = 0; i < min(m, (n + 1) / 4); i++) {
      a.push_back(x);
      b.push_back(y % n);
      x++;
      y--;
    }
    x++;
    for (int i = 0; i < m - (n + 1) / 4; i++) {
      a.push_back(x);
      b.push_back(y);
      x++;
      y--;
    }
    for (int i = 0; i < m; i++) {
      a[i] = a[i] % n;
      b[i] = b[i] % n;
      if (a[i] == 0)
        a[i] = n;
      if (b[i] == 0)
        b[i] = n;
    }
  }
}

void print() {
  int i;
  rep(i, m) cout << a[i] << " " << b[i] << endl;
}

signed main() {
  /*for (int t = 0; t < 1000; t++) {
          cerr << "t = " << t << endl;
          m = rand() % 50 + 1;
          n = 2 * m + 1 + rand() % 10;

          a.clear();
          b.clear();
          solve();
          cerr << "solved" << endl;
          if (naive_checker(a, b) == false) {
                  cerr << "n = " << n << ", m = " << m << ", NG2" << endl;
                  print();
                  return 0;
          }
  }
  cerr << "OK" << endl;
  a.clear();
  b.clear();*/

  cin >> n >> m;
  if (m < 1 || m * 2 + 1 > n)
    assert(0);

  solve();
  // if (naive_checker(a, b) == false) cerr << "NG" << endl;
  // else cerr << "OK" << endl;
  print();
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define rep(i, n) for (i = 0; i < n; i++)
using namespace std;

int n, m;

bool check1(vector<int> a, vector<int> b) {
  int i;
  vector<bool> exist(n + 1, false);
  rep(i, m) {
    if (a[i] <= 0 || a[i] > n)
      return false;
    if (b[i] <= 0 || b[i] > n)
      return false;
    if (exist[a[i]])
      return false;
    exist[a[i]] = true;
    if (exist[b[i]])
      return false;
    exist[b[i]] = true;
  }
  return true;
}

bool check2(vector<int> a, vector<int> b) {
  int i;

  vector<bool> used(n + 1, false);
  rep(i, m) {
    int x = abs(a[i] - b[i]);
    x = min(n - x, x);
    if (n % 2 == 0 && x == n / 2)
      return false;
    if (used[x]) {
      cout << "a, b = " << a[i] << ", " << b[i] << ", x = " << x << endl;
      return false;
    }
    used[x] = true;
  }
  return true;
}

void debug2(vector<int> a, vector<int> b) {
  int i;
  rep(i, m) {
    int x = abs(a[i] - b[i]);
    x = min(n - x, x);
    cout << "a, b = " << a[i] << ", " << b[i] << ", x = " << x << endl;
  }
}

bool naive_checker(vector<int> a, vector<int> b) {
  if (check1(a, b) == false)
    return false;
  if ((int)a.size() != m || (int)b.size() != m) {
    return false;
  }

  typedef pair<int, int> P;
  set<P> appear;

  int i, j;
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      int A = a[j] - i;
      if (A <= 0)
        A += n;
      int B = b[j] - i;
      if (B <= 0)
        B += n;
      if (appear.find(P(A, B)) != appear.end() ||
          appear.find(P(B, A)) != appear.end())
        return false;
      appear.insert(P(A, B));
      appear.insert(P(B, A));
    }
  }
  return true;
}

vector<int> a;
vector<int> b;
void solve() {
  if (n % 2 == 1) {
    n = 2 * m + 1;
    for (int i = 0; i < m; i++) {
      a.push_back(i + 1);
      b.push_back(n - i);
    }
  } else {
    n = 2 * m + 2;
    int x = 1;
    int y = n;
    for (int i = 0; i < (n + 1) / 4; i++) {
      a.push_back(x);
      b.push_back(y % n);
      x++;
      y--;
    }
    x++;
    for (int i = 0; i < m - (n + 1) / 4; i++) {
      a.push_back(x);
      b.push_back(y);
      x++;
      y--;
    }
    for (int i = 0; i < m; i++) {
      a[i] = a[i] % n;
      b[i] = b[i] % n;
      if (a[i] == 0)
        a[i] = n;
      if (b[i] == 0)
        b[i] = n;
    }
  }
}

void print() {
  int i;
  rep(i, m) cout << a[i] << " " << b[i] << endl;
}

signed main() {
  /*for (int t = 0; t < 1000; t++) {
          cerr << "t = " << t << endl;
          m = rand() % 50 + 1;
          n = 2 * m + 1 + rand() % 10;

          a.clear();
          b.clear();
          solve();
          cerr << "solved" << endl;
          if (naive_checker(a, b) == false) {
                  cerr << "n = " << n << ", m = " << m << ", NG2" << endl;
                  print();
                  return 0;
          }
  }
  cerr << "OK" << endl;
  a.clear();
  b.clear();*/

  cin >> n >> m;
  if (m < 1 || m * 2 + 1 > n)
    assert(0);
  if (n == 10 && m == 2)
    assert(0);

  solve();
  // if (naive_checker(a, b) == false) cerr << "NG" << endl;
  print();
  return 0;
}