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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
using namespace std;
bool used[1000][80];
int dx[] = {-1, +0, +1, +1, +1, +0, -1, -1};
int dy[] = {+1, +1, +1, +0, -1, -1, -1, +0};

class Point {
public:
  double x, y;

  Point(double x = -1, double y = -1) : 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); } // ※イケメンに限る

  bool operator<(const Point &p) const { return y != p.y ? y < p.y : x < p.x; }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(-1, -1), Point p2 = Point(-1, -1))
      : p1(p1), p2(p2) {}
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

void dfs(int x, int y, vector<Point> &vec, vector<string> &G, int H) {
  if (used[y][x])
    return;
  used[y][x] = true;
  vec.push_back(Point(x, y));

  rep(i, 8) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (!(0 <= ny && ny < H && 0 <= nx && nx < G[ny].size()))
      continue;
    if (G[ny][nx] == '*' && !used[ny][nx]) {
      dfs(nx, ny, vec, G, H);
      return;
    }
  }
}

int calc(vector<Point> &vec) {
  int res = 0;
  // cout << "vec[] = " << vec.size() << endl;
  rep(i, vec.size()) {
    int j, cnt = 0;
    for (j = i; j < vec.size() && vec[j].y == vec[i].y; j++, cnt++)
      ;
    assert(cnt >= 2);
    if (cnt == 2)
      res += vec[i + 1].x - vec[i].x + 1;
    else
      res += cnt;
    i = j - 1;
  }
  return res;
}

int main() {
  int n;
  bool f = true;
  while (cin >> n, n) {
    cin.ignore();
    vector<string> G(n);
    string input;
    rep(i, n) {
      getline(cin, input);
      G[i] = input;
    }

    rep(i, n) rep(j, G[i].size()) used[i][j] = false;

    map<int, int> ans;

    rep(i, n) {
      rep(j, G[i].size()) {
        if (G[i][j] != '*')
          continue;
        if (used[i][j])
          continue;
        vector<Point> vec;
        dfs(j, i, vec, G, n);
        /*
rep(k,vec.size())
          cout << vec[k].x << "," << vec[k].y << endl;
        cout << endl;
        */
        sort(vec.begin(), vec.end());

        int area = calc(vec);
        ans[area]++;
      }
    }

    if (f)
      f = false;
    else
      cout << "----------" << endl;

    for (map<int, int>::iterator it = ans.begin(); it != ans.end(); it++)
      cout << it->first << " " << it->second << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
using namespace std;
bool used[80][1000];
int dx[] = {-1, +0, +1, +1, +1, +0, -1, -1};
int dy[] = {+1, +1, +1, +0, -1, -1, -1, +0};

class Point {
public:
  double x, y;

  Point(double x = -1, double y = -1) : 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); } // ※イケメンに限る

  bool operator<(const Point &p) const { return y != p.y ? y < p.y : x < p.x; }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(-1, -1), Point p2 = Point(-1, -1))
      : p1(p1), p2(p2) {}
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

void dfs(int x, int y, vector<Point> &vec, vector<string> &G, int H) {
  if (used[y][x])
    return;
  used[y][x] = true;
  vec.push_back(Point(x, y));

  rep(i, 8) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (!(0 <= ny && ny < H && 0 <= nx && nx < G[ny].size()))
      continue;
    if (G[ny][nx] == '*' && !used[ny][nx]) {
      dfs(nx, ny, vec, G, H);
      return;
    }
  }
}

int calc(vector<Point> &vec) {
  int res = 0;
  // cout << "vec[] = " << vec.size() << endl;
  rep(i, vec.size()) {
    int j, cnt = 0;
    for (j = i; j < vec.size() && vec[j].y == vec[i].y; j++, cnt++)
      ;
    assert(cnt >= 2);
    if (cnt == 2)
      res += vec[i + 1].x - vec[i].x + 1;
    else
      res += cnt;
    i = j - 1;
  }
  return res;
}

int main() {
  int n;
  bool f = true;
  while (cin >> n, n) {
    cin.ignore();
    vector<string> G(n);
    string input;
    rep(i, n) {
      getline(cin, input);
      G[i] = input;
    }

    rep(i, n) rep(j, G[i].size()) used[i][j] = false;

    map<int, int> ans;

    rep(i, n) {
      rep(j, G[i].size()) {
        if (G[i][j] != '*')
          continue;
        if (used[i][j])
          continue;
        vector<Point> vec;
        dfs(j, i, vec, G, n);
        /*
rep(k,vec.size())
          cout << vec[k].x << "," << vec[k].y << endl;
        cout << endl;
        */
        sort(vec.begin(), vec.end());

        int area = calc(vec);
        ans[area]++;
      }
    }

    if (f)
      f = false;
    else
      cout << "----------" << endl;

    for (map<int, int>::iterator it = ans.begin(); it != ans.end(); it++)
      cout << it->first << " " << it->second << endl;
  }
  return 0;
}