Problem p00901 (C++)

Buggy submission (status: Runtime Error):
#include <cctype>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;

int mod = 2011;

int inv[2011];

int ruijo(int x, int n) {
  int p, ans;
  if (n == 0)
    return 1;
  if (n == 1)
    return x;
  if (n % 2) {
    p = ruijo(x, n / 2);
    ans = (x * p) % mod;
    ans = (ans * p) % mod;
    return ans;
  } else {
    p = ruijo(x, n / 2);
    ans = (p * p) % mod;
    return ans;
  }
}
int n;
int m;
vector<string> v;

int expr(int a, int b, int c, int d);
int term(int a, int b, int c, int d);
int factor(int a, int b, int c, int d);
int powexpr(int a, int b, int c, int d);
int primary(int a, int b, int c, int d);

int expr(int a, int b, int c, int d) {
  // cout << "expr " << a << " " << b << " " << c << " " << d <<endl;
  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return expr(a, b + 1, c, d);
  }
  int x_tmp = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][d] != '.')
      x_tmp = i;
  }
  if (x_tmp == -1) {
    return expr(a, b, c, d - 1);
  }
  int y = b;
  int yt = -1;
  int depth = 0;
  for (int i = b; i <= d; i++) {
    if (v[x][i] == '(') {
      depth++;
    } else if (v[x][i] == ')') {
      depth--;
    } else if (depth == 0 &&
               (v[x][i] == '*' || v[x][i] == '+' || v[x][i] == '-')) {
      if (v[x][i] == '+') {
        y = i;
        yt = i;
      } else if (v[x][i] == '*') {
        yt = i;
      } else {
        if (i != d) {
          if (v[x][i] == '-' && v[x][i + 1] == '.' && i < d - 1) {
            if (yt + 2 == i) {
              yt = i;
            } else {
              y = i;
              yt = i;
            }
          }
        }
      }
    }
  }
  if (y == b) {
    return term(a, b, c, d);
  } else {
    if (v[x][y] == '-') {
      return (mod + expr(a, b, c, y - 2) - term(a, y + 2, c, d)) % mod;
    } else {
      return (expr(a, b, c, y - 2) + term(a, y + 2, c, d)) % mod;
    }
  }
}

int term(int a, int b, int c, int d) {
  // cout << "term " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return term(a, b + 1, c, d);
  }
  int y = b;
  int depth = 0;
  for (int i = b; i <= d; i++) {
    if (v[x][i] == '(') {
      depth++;
    } else if (v[x][i] == ')') {
      depth--;
    } else if (depth == 0 && v[x][i] == '*') {
      y = i;
    }
  }
  if (y == b) {
    return factor(a, b, c, d);
  } else {
    return (term(a, b, c, y - 2) * factor(a, y + 2, c, d)) % mod;
  }
}

int factor(int a, int b, int c, int d) {
  // cout << "factor " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return factor(a, b + 1, c, d);
  }
  if (v[x][b] != '-') {
    return powexpr(a, b, c, d);
  }
  if (v[x][b + 1] == '-') {
    return (expr(a, b, x - 1, d) * inv[expr(x + 1, b, c, d)]) % mod;
  } else {
    return (mod - factor(a, b + 2, c, d)) % mod;
  }
}

int powexpr(int a, int b, int c, int d) {
  // cout << "powexpr " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return powexpr(a, b + 1, c, d);
  }
  if (v[x][b] == '(') {
    int depth = 0;
    for (int i = b; i <= d; i++) {
      if (v[x][i] == '(') {
        depth++;
      }
      if (v[x][i] == ')') {
        depth--;
        if (depth == 0) {
          if (x != 0 && i < d) {
            if (v[x - 1][i + 1] != '.' && v[x - 1][b + 1] != '-') {

              return ruijo(expr(a, b + 1, c, i - 1), v[x - 1][i + 1] - '0');
            }
          }
          return expr(a, b + 1, c, i - 1);
        }
      }
    }
  } else {
    if (x != 0 && b < d) {
      if (v[x - 1][b + 1] != '.' && v[x - 1][b + 1] != '-') {
        return ruijo(v[x][b] - '0', v[x - 1][b + 1] - '0');
      }
    }
    return v[x][b] - '0';
  }
}

int main() {
  for (int i = 1; i < 2011; i++) {
    inv[i] = ruijo(i, 2009);
  }
  while (cin >> n && n != 0) {
    v.clear();
    for (int i = 0; i < n; i++) {
      string tmp;
      cin >> tmp;
      v.push_back(tmp);
    }
    m = v[0].size();
    int ans = 0;
    ans = expr(0, 0, n - 1, m - 1);
    cout << ans << endl;
  }
  return 0;
}


Fixed submission:
#include <cctype>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;

int mod = 2011;

int inv[2011];

int ruijo(int x, int n) {
  int p, ans;
  if (n == 0)
    return 1;
  if (n == 1)
    return x;
  if (n % 2) {
    p = ruijo(x, n / 2);
    ans = (x * p) % mod;
    ans = (ans * p) % mod;
    return ans;
  } else {
    p = ruijo(x, n / 2);
    ans = (p * p) % mod;
    return ans;
  }
}
int n;
int m;
vector<string> v;

int expr(int a, int b, int c, int d);
int term(int a, int b, int c, int d);
int factor(int a, int b, int c, int d);
int powexpr(int a, int b, int c, int d);
int primary(int a, int b, int c, int d);

int expr(int a, int b, int c, int d) {
  // cout << "expr " << a << " " << b << " " << c << " " << d <<endl;
  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return expr(a, b + 1, c, d);
  }
  int x_tmp = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][d] != '.')
      x_tmp = i;
  }
  if (x_tmp == -1) {
    return expr(a, b, c, d - 1);
  }
  int y = b;
  int yt = -1;
  int depth = 0;
  for (int i = b; i <= d; i++) {
    if (v[x][i] == '(') {
      depth++;
    } else if (v[x][i] == ')') {
      depth--;
    } else if (depth == 0 &&
               (v[x][i] == '*' || v[x][i] == '+' || v[x][i] == '-')) {
      if (v[x][i] == '+') {
        y = i;
        yt = i;
      } else if (v[x][i] == '*') {
        yt = i;
      } else {
        if (i == 0) {
          if (v[x][i] == '-' && v[x][i + 1] == '.') {
            yt = 0;
          }
        }
        if (i != d && i != 0) {
          if (v[x][i] == '-' && v[x][i + 1] == '.' && v[x][i - 1] == '.') {
            if (yt + 2 == i) {
              yt = i;
            } else {
              y = i;
              yt = i;
            }
          }
        }
      }
    }
  }
  if (y == b) {
    return term(a, b, c, d);
  } else {
    if (v[x][y] == '-') {
      return (mod + expr(a, b, c, y - 2) - term(a, y + 2, c, d)) % mod;
    } else {
      return (expr(a, b, c, y - 2) + term(a, y + 2, c, d)) % mod;
    }
  }
}

int term(int a, int b, int c, int d) {
  // cout << "term " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return term(a, b + 1, c, d);
  }
  int y = b;
  int depth = 0;
  for (int i = b; i <= d; i++) {
    if (v[x][i] == '(') {
      depth++;
    } else if (v[x][i] == ')') {
      depth--;
    } else if (depth == 0 && v[x][i] == '*') {
      y = i;
    }
  }
  if (y == b) {
    return factor(a, b, c, d);
  } else {
    return (term(a, b, c, y - 2) * factor(a, y + 2, c, d)) % mod;
  }
}

int factor(int a, int b, int c, int d) {
  // cout << "factor " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return factor(a, b + 1, c, d);
  }
  if (v[x][b] != '-') {
    return powexpr(a, b, c, d);
  }
  if (v[x][b + 1] == '-') {
    return (expr(a, b, x - 1, d) * inv[expr(x + 1, b, c, d)]) % mod;
  } else {
    return (mod - factor(a, b + 2, c, d)) % mod;
  }
}

int powexpr(int a, int b, int c, int d) {
  // cout << "powexpr " << a << " " << b << " " << c << " " << d <<endl;

  int x = -1;
  for (int i = a; i <= c; i++) {
    if (v[i][b] != '.')
      x = i;
  }
  if (x == -1) {
    return powexpr(a, b + 1, c, d);
  }
  if (v[x][b] == '(') {
    int depth = 0;
    for (int i = b; i <= d; i++) {
      if (v[x][i] == '(') {
        depth++;
      }
      if (v[x][i] == ')') {
        depth--;
        if (depth == 0) {
          if (x != 0 && i < d) {
            if (v[x - 1][i + 1] != '.' && v[x - 1][b + 1] != '-') {

              return ruijo(expr(a, b + 1, c, i - 1), v[x - 1][i + 1] - '0');
            }
          }
          return expr(a, b + 1, c, i - 1);
        }
      }
    }
  } else {
    if (x != 0 && b < d) {
      if (v[x - 1][b + 1] != '.' && v[x - 1][b + 1] != '-') {
        return ruijo(v[x][b] - '0', v[x - 1][b + 1] - '0');
      }
    }
    return v[x][b] - '0';
  }
}

int main() {
  for (int i = 1; i < 2011; i++) {
    inv[i] = ruijo(i, 2009);
  }
  while (cin >> n && n != 0) {
    v.clear();
    for (int i = 0; i < n; i++) {
      string tmp;
      cin >> tmp;
      v.push_back(tmp);
    }
    m = v[0].size();
    int ans = 0;
    ans = expr(0, 0, n - 1, m - 1);
    cout << ans << endl;
  }
  return 0;
}