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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef ll li;
typedef pair<int, int> PI;
#define EPS (1e-10L)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define REP(i, n) rep(i, n)
#define F first
#define S second
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(), a.end()
#define CLR(a) memset((a), 0, sizeof(a))
#define FOR(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
template <typename T, typename U>
ostream &operator<<(ostream &out, const pair<T, U> &val) {
  return out << "(" << val.F << ", " << val.S << ")";
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &val) {
  out << "{";
  rep(i, SZ(val)) out << (i ? ", " : "") << val[i];
  return out << "}";
}
void pkuassert(bool t) { t = 1 / t; };
int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[] = {1, 0, -1, 0, -1, 1, 1, -1};

int n;
string in[20];
int inv[3000];

void normal(int &x1, int &y1, int &x2, int &y2) {
  set<int> x, y;
  for (int i = x1; i < x2; ++i)
    for (int j = y1; j < y2; ++j) {
      if (in[i][j] != '.') {
        x.insert(i);
        y.insert(j);
      }
    }
  x1 = *x.begin();
  x2 = *x.rbegin() + 1;
  y1 = *y.begin();
  y2 = *y.rbegin() + 1;
}

int expr(int, int, int, int);
int term(int, int, int, int);
int factor(int, int, int, int);
int powexpr(int, int, int, int);
int primary(int, int, int, int);

int digit(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "digit " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int ret = 0;
  while (y1 < y2 && isdigit(in[x1][y1]))
    ret = (ret * 10 + in[x1][y1++] - '0') % 2011;
  return ret;
}

int primary(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "primary " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  if (in[base][y1] == '(')
    return expr(x1, y1 + 1, x2, y2 - 1);
  return digit(x1, y1, x2, y2);
}

int fraction(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int p = expr(base + 1, y1, x2, y2);
  int c = expr(x1, y1, base, y2);
  return c * inv[p] % 2011;
}

int powexpr(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "powexpr " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int base;
  int base2 = -1;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  for (int j = x1; j < x2; ++j)
    if (in[j][y2 - 1] != '.')
      base2 = j;
  // cout << base << ' ' << base2 << endl;
  if (base2 == base)
    return primary(x1, y1, x2, y2);

  int idx = y2 - 1;
  while (idx >= y1 && isdigit(in[base2][idx]))
    --idx;
  ++idx;
  int di = digit(base2, idx, base2 + 1, y2);
  int pr = primary(x1, y1, x2, idx);
  // cout << "pr di " << pr << ' ' << di << endl;
  int ret = 1;
  rep(i, di) ret = (ret * pr) % 2011;
  return ret;
}

int factor(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "factor " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int ret;
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;

  if (in[base][y1] == '-' && y1 + 1 < y2 && in[base][y1 + 1] == '.')
    return ((-factor(x1, y1 + 2, x2, y2)) % 2011 + 2011) % 2011;

  if (in[base][y1] == '-' && y1 + 1 < y2 && in[base][y1 + 1] == '-')
    return fraction(x1, y1, x2, y2);

  return powexpr(x1, y1, x2, y2);
}

int term(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int ret;
  int base;
  // cout << "term " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int idx = -1;
  int pa = 0;
  for (int j = y1; j < y2; ++j) {
    if (in[base][j] == '(')
      ++pa;
    if (in[base][j] == ')')
      --pa;
    if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
        in[base][j] == '*' && in[base][j + 1] == '.' && pa == 0) {
      idx = j;
      break;
    }
  }

  if (idx != -1)
    ret = factor(x1, y1, x2, idx - 1);
  else
    return factor(x1, y1, x2, y2);
  y1 = idx + 1;
  while (true) {

    normal(x1, y1, x2, y2);
    idx = -1;
    int pa = 0;

    for (int j = y1; j < y2; ++j) {
      if (in[base][j] == '(')
        ++pa;
      if (in[base][j] == ')')
        --pa;
      if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
          in[base][j] == '*' && in[base][j + 1] == '.' && pa == 0) {
        idx = j;
        break;
      }
    }

    if (idx != -1) {
      int t = factor(x1, y1, x2, idx - 1);
      ret = (ret * t) % 2011;
    } else {
      int t = factor(x1, y1, x2, y2);
      ret = (ret * t) % 2011;
      return ret;
    }
    y1 = idx + 1;
  }
  return ret;
}

int expr(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int ret;
  int base;
  /*
  cout << "expr " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  for(int i=x1;i<x2;++i){
    for(int j=y1;j<y2;++j) cout << in[i][j];
    cout << endl;
  }
  */
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int idx = -1;
  int pa = 0;
  for (int j = y1; j < y2; ++j) {
    if (in[base][j] == '(')
      ++pa;
    if (in[base][j] == ')')
      --pa;
    if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
        (in[base][j] == '+' ||
         (in[base][j] == '-' &&
          (j - 2 >= 0 && in[base][j - 2] != '*' && in[base][j - 2] != '+' &&
           (in[base][j - 2] != '-' ||
            (j - 3 >= 0 && in[base][j - 3] == '-'))))) &&
        in[base][j + 1] == '.' && pa == 0) {
      idx = j;
      break;
    }
  }

  if (idx != -1)
    ret = term(x1, y1, x2, idx - 1);
  else
    return term(x1, y1, x2, y2);
  y1 = idx + 1;
  while (true) {
    normal(x1, y1, x2, y2);
    char op = in[base][idx];
    idx = -1;
    int pa = 0;
    for (int j = y1; j < y2; ++j) {
      if (in[base][j] == '(')
        ++pa;
      if (in[base][j] == ')')
        --pa;
      if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
          (in[base][j] == '+' ||
           (in[base][j] == '-' &&
            (j - 2 >= 0 && in[base][j - 2] != '*' && in[base][j - 2] != '+' &&
             (in[base][j - 2] != '-' ||
              (j - 3 >= 0 && in[base][j - 3] == '-'))))) &&
          in[base][j + 1] == '.' && pa == 0) {
        idx = j;
        break;
      }
    }

    if (idx != -1) {
      int t = term(x1, y1, x2, idx - 1);
      if (op == '+')
        ret = (ret + t) % 2011;
      else
        ret = ((ret - t) % 2011 + 2011) % 2011;
    } else {
      int t = term(x1, y1, x2, y2);
      // cout << op << ' ' << t << endl;
      if (op == '+')
        ret = (ret + t) % 2011;
      else
        ret = ((ret - t) % 2011 + 2011) % 2011;
      return ret;
    }
    y1 = idx + 1;
  }
  return ret;
}

void solve() {
  rep(i, n) cin >> in[i];
  // rep(i, n) cout << in[i] << endl;
  cout << expr(0, 0, n, SZ(in[0])) << endl;
}

int main(int argc, char *argv[]) {
  rep(i, 2011) rep(j, 2011) if (i * j % 2011 == 1) inv[i] = j;
  // cout << 4*inv[9] << endl;
  while (cin >> n && n)
    solve();
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef ll li;
typedef pair<int, int> PI;
#define EPS (1e-10L)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define REP(i, n) rep(i, n)
#define F first
#define S second
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(), a.end()
#define CLR(a) memset((a), 0, sizeof(a))
#define FOR(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
template <typename T, typename U>
ostream &operator<<(ostream &out, const pair<T, U> &val) {
  return out << "(" << val.F << ", " << val.S << ")";
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &val) {
  out << "{";
  rep(i, SZ(val)) out << (i ? ", " : "") << val[i];
  return out << "}";
}
void pkuassert(bool t) { t = 1 / t; };
int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[] = {1, 0, -1, 0, -1, 1, 1, -1};

int n;
string in[20];
int inv[3000];

void normal(int &x1, int &y1, int &x2, int &y2) {
  set<int> x, y;
  for (int i = x1; i < x2; ++i)
    for (int j = y1; j < y2; ++j) {
      if (in[i][j] != '.') {
        x.insert(i);
        y.insert(j);
      }
    }
  x1 = *x.begin();
  x2 = *x.rbegin() + 1;
  y1 = *y.begin();
  y2 = *y.rbegin() + 1;
}

int expr(int, int, int, int);
int term(int, int, int, int);
int factor(int, int, int, int);
int powexpr(int, int, int, int);
int primary(int, int, int, int);

int digit(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "digit " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int ret = 0;
  while (y1 < y2 && isdigit(in[x1][y1]))
    ret = (ret * 10 + in[x1][y1++] - '0') % 2011;
  return ret;
}

int primary(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "primary " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  if (in[base][y1] == '(')
    return expr(x1, y1 + 1, x2, y2 - 1);
  return digit(x1, y1, x2, y2);
}

int fraction(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int p = expr(base + 1, y1, x2, y2);
  int c = expr(x1, y1, base, y2);
  return c * inv[p] % 2011;
}

int powexpr(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "powexpr " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int base;
  int base2 = -1;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  for (int j = x1; j < x2; ++j)
    if (in[j][y2 - 1] != '.')
      base2 = j;
  // cout << base << ' ' << base2 << endl;
  if (base2 == base)
    return primary(x1, y1, x2, y2);

  int idx = y2 - 1;
  while (idx >= y1 && isdigit(in[base2][idx]))
    --idx;
  ++idx;
  int di = digit(base2, idx, base2 + 1, y2);
  int pr = primary(x1, y1, x2, idx);
  // cout << "pr di " << pr << ' ' << di << endl;
  int ret = 1;
  rep(i, di) ret = (ret * pr) % 2011;
  return ret;
}

int factor(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  // cout << "factor " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  int ret;
  int base;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;

  if (in[base][y1] == '-' && y1 + 1 < y2 && in[base][y1 + 1] == '.')
    return ((-factor(x1, y1 + 2, x2, y2)) % 2011 + 2011) % 2011;

  if (in[base][y1] == '-' && y1 + 1 < y2 && in[base][y1 + 1] == '-')
    return fraction(x1, y1, x2, y2);

  return powexpr(x1, y1, x2, y2);
}

int term(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int ret;
  int base;
  // cout << "term " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int idx = -1;
  int pa = 0;
  for (int j = y1; j < y2; ++j) {
    if (in[base][j] == '(')
      ++pa;
    if (in[base][j] == ')')
      --pa;
    if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
        in[base][j] == '*' && in[base][j + 1] == '.' && pa == 0) {
      idx = j;
      break;
    }
  }

  if (idx != -1)
    ret = factor(x1, y1, x2, idx - 1);
  else
    return factor(x1, y1, x2, y2);
  y1 = idx + 1;
  while (true) {

    normal(x1, y1, x2, y2);
    idx = -1;
    int pa = 0;

    for (int j = y1; j < y2; ++j) {
      if (in[base][j] == '(')
        ++pa;
      if (in[base][j] == ')')
        --pa;
      if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
          in[base][j] == '*' && in[base][j + 1] == '.' && pa == 0) {
        idx = j;
        break;
      }
    }

    if (idx != -1) {
      int t = factor(x1, y1, x2, idx - 1);
      ret = (ret * t) % 2011;
    } else {
      int t = factor(x1, y1, x2, y2);
      ret = (ret * t) % 2011;
      return ret;
    }
    y1 = idx + 1;
  }
  return ret;
}

int expr(int x1, int y1, int x2, int y2) {
  normal(x1, y1, x2, y2);
  int ret;
  int base;
  // cout << "expr " << x1 << ' ' <<  y1 << ' ' << x2 << ' ' << y2 << endl;
  for (int j = x1; j < x2; ++j)
    if (in[j][y1] != '.')
      base = j;
  int idx = -1;
  int pa = 0;
  for (int j = y1; j < y2; ++j) {
    if (in[base][j] == '(')
      ++pa;
    if (in[base][j] == ')')
      --pa;
    if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
        (in[base][j] == '+' ||
         (in[base][j] == '-' &&
          (j - 2 >= 0 && in[base][j - 2] != '*' && in[base][j - 2] != '+' &&
           in[base][j - 2] != '-'))) &&
        in[base][j + 1] == '.' && pa == 0) {
      idx = j;
      break;
    }
  }

  if (idx != -1)
    ret = term(x1, y1, x2, idx - 1);
  else
    return term(x1, y1, x2, y2);
  y1 = idx + 1;
  while (true) {
    normal(x1, y1, x2, y2);
    char op = in[base][idx];
    idx = -1;
    int pa = 0;
    for (int j = y1; j < y2; ++j) {
      if (in[base][j] == '(')
        ++pa;
      if (in[base][j] == ')')
        --pa;
      if (j - 1 >= y1 && j + 1 < y2 && in[base][j - 1] == '.' &&
          (in[base][j] == '+' ||
           (in[base][j] == '-' &&
            (j - 2 >= 0 && in[base][j - 2] != '*' && in[base][j - 2] != '+' &&
             in[base][j - 2] != '-'))) &&
          in[base][j + 1] == '.' && pa == 0) {
        idx = j;
        break;
      }
    }

    if (idx != -1) {
      int t = term(x1, y1, x2, idx - 1);
      if (op == '+')
        ret = (ret + t) % 2011;
      else
        ret = ((ret - t) % 2011 + 2011) % 2011;
    } else {
      int t = term(x1, y1, x2, y2);
      // cout << op << ' ' << t << endl;
      if (op == '+')
        ret = (ret + t) % 2011;
      else
        ret = ((ret - t) % 2011 + 2011) % 2011;
      return ret;
    }
    y1 = idx + 1;
  }
  return ret;
}

void solve() {
  rep(i, n) cin >> in[i];
  cout << expr(0, 0, n, SZ(in[0])) << endl;
}

int main(int argc, char *argv[]) {
  rep(i, 2011) rep(j, 2011) if (i * j % 2011 == 1) inv[i] = j;
  // cout << 4*inv[9] << endl;
  while (cin >> n && n)
    solve();
  return 0;
}