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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

#define EPS 1e-9
#define x first
#define y second
#define mkp make_pair

typedef pair<double, double> pdd;

vector<pdd> polygon;
vector<vector<pdd>> pts;
vector<pdd> chkpts;
vector<bitset<1000>> visible_pts;
vector<bitset<1000>> visible_seg;

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

template <class T> T sqr(T x) { return x * x; }

double dist(pdd a, pdd b) {
  pdd c;
  c.x = b.x - a.x;
  c.y = b.y - a.y;
  return sqrt(c.x * c.x + c.y * c.y);
}

bool eq_pt(pdd a, pdd b) { return dist(a, b) < EPS; }

bool on_seg(pdd pt, pdd a, pdd b) {
  pdd c, d;
  c.x = a.x - pt.x;
  c.y = a.y - pt.y;
  d.x = b.x - pt.x;
  d.y = b.y - pt.y;
  return (dot(c, d) < EPS) && (fabs(cross(c, d)) < EPS);
}

bool parallel(pdd li0s, pdd li0t, pdd li1s, pdd li1t) {
  pdd a, b;
  a = mkp(li0t.x - li0s.x, li0t.y - li0s.y);
  b = mkp(li1t.x - li1s.x, li1t.y - li1s.y);
  return fabs(cross(a, b)) < EPS;
}

pdd intersection(pdd li0s, pdd li0t, pdd li1s, pdd li1t) {
  double s, t;
  pdd a, b, c;

  a = mkp(li1s.x - li0s.x, li1s.y - li0s.y);
  b = mkp(li1t.x - li0s.x, li1t.y - li0s.y);
  c = mkp(li0t.x - li0s.x, li0t.y - li0s.y);

  if (fabs(cross(a, b)) < EPS)
    return li0s;

  s = cross(a, c) / cross(a, b);
  t = cross(c, b) / cross(a, b);

  return mkp(li0s.x + c.x / (s + t), li0s.y + c.y / (s + t));
}

void mkpts() {
  pts.resize(polygon.size());
  for (int i = 0; i < polygon.size(); i++) {
    pdd li0s = polygon[i];
    for (int j = 1; j < polygon.size(); j++) {
      pdd li0t = polygon[(i + j) % polygon.size()];
      for (int k = 0; k < polygon.size(); k++) {
        pdd li1s, li1t, res;
        li1s = polygon[k];
        li1t = polygon[(k + 1) % polygon.size()];
        if (parallel(li0s, li0t, li1s, li1t))
          continue;
        res = intersection(li0s, li0t, li1s, li1t);
        if (on_seg(res, li1s, li1t))
          pts[k].push_back(res);
      }
    }
  }
  for (int i = 0; i < polygon.size(); i++)
    pts[i].push_back(polygon[i]);
}

pdd cmpbase;
bool cmp(pdd a, pdd b) { return dist(cmpbase, a) < dist(cmpbase, b); }

void mkchkpts() {
  for (int i = 0; i < pts.size(); i++) {
    cmpbase = polygon[i];
    sort(pts[i].begin(), pts[i].end(), cmp);
  }
  chkpts.push_back(pts[0][0]);
  for (int i = 0; i < pts.size(); i++) {
    for (int j = 0; j < pts[i].size(); j++) {
      if (dist(chkpts.back(), pts[i][j]) > EPS)
        chkpts.push_back(pts[i][j]);
    }
  }
}

bool valid_angle(int indx, pdd p) {
  int sz = polygon.size();

  pdd a, b;
  a = mkp(polygon[indx].x - polygon[(indx - 1 + sz) % sz].x,
          polygon[indx].y - polygon[(indx - 1 + sz) % sz].y);
  b = mkp(polygon[(indx + sz + 1) % sz].x - polygon[indx].x,
          polygon[(indx + sz + 1) % sz].y - polygon[indx].y);

  pdd aa, bb;
  aa = mkp(p.x - polygon[(indx - 1 + sz) % sz].x,
           p.y - polygon[(indx - 1 + sz) % sz].y);
  bb = mkp(p.x - polygon[indx].x, p.y - polygon[indx].y);

  if (cross(a, b) > 0)
    return (cross(a, aa) + EPS > 0) && (cross(b, bb) + EPS > 0);
  else
    return (cross(a, aa) + EPS > 0) || (cross(b, bb) + EPS > 0);
}

bool seen(pdd a, pdd b) {
  pdd c = mkp(b.x - a.x, b.y - a.y);
  if (eq_pt(a, b))
    return true;

  for (int i = 0; i < polygon.size(); i++) {
    pdd seg0s, seg0t;
    seg0s = polygon[i];
    seg0t = polygon[(i + 1) % polygon.size()];
    if (parallel(seg0s, seg0t, a, b))
      continue;
    pdd p = intersection(seg0s, seg0t, a, b);
    if (!on_seg(p, a, b) || eq_pt(p, a) || eq_pt(p, b))
      continue;
    if (!on_seg(p, seg0s, seg0t))
      continue;

    int indx = -1;
    for (int j = 0; j < polygon.size(); j++) {
      if (eq_pt(p, polygon[j])) {
        indx = j;
      }
    }
    if (!(indx + 1))
      return false;

    int sz = polygon.size();
    pdd v, w;
    v = mkp(polygon[(indx - 1 + sz) % sz].x - p.x,
            polygon[(indx - 1 + sz) % sz].y - p.y);
    w = mkp(polygon[(indx + 1) % sz].x - p.x, polygon[(indx + 1) % sz].y - p.y);
    if (cross(v, c) * cross(w, c) + EPS < 0) {
      return false;
    }
    if (!valid_angle(indx, b)) {
      return false;
    }
  }
  return true;
}

void mkvisible() {
  visible_pts.resize(polygon.size());
  visible_seg.resize(polygon.size());
  for (int i = 0; i < visible_pts.size(); i++) {
    visible_pts[i].reset();
    visible_seg[i].reset();
  }
  for (int i = 0; i < polygon.size(); i++) {
    for (int j = 0; j < chkpts.size(); j++) {
      if (valid_angle(i, chkpts[j]))
        visible_pts[i][j] = seen(polygon[i], chkpts[j]);
      else
        visible_pts[i][j] = false;
    }
  }
  for (int i = 0; i < visible_pts.size(); i++) {
    for (int j = 0; j < chkpts.size(); j++) {
      visible_seg[i][j] =
          visible_pts[i][j] && visible_pts[i][(j + 1) % chkpts.size()];
    }
  }
}

int solve() {
  int res, sz;
  res = sz = polygon.size();

  for (int i = 0; i < (1 << sz); i++) {
    bitset<1000> bs;
    bs.reset();
    int cnt = 0;
    for (int j = 0; j < sz; j++) {
      if (i & (1 << j)) {
        cnt++;
        for (int k = 0; k < chkpts.size(); k++) {
          if (visible_seg[j][k])
            bs[k] = true;
        }
      }
    }
    bool flg = true;
    for (int j = 0; j < chkpts.size(); j++) {
      flg &= bs[j];
    }
    if (flg) {
      res = min(res, cnt);
    }
  }
  return res;
}

int main() {
  int n;

  while (cin >> n, n) {
    polygon.clear();
    pts.clear();
    chkpts.clear();
    visible_pts.clear();
    visible_seg.clear();

    polygon.resize(n);
    for (int i = 0; i < n; i++) {
      cin >> polygon[i].x >> polygon[i].y;
    }
    mkpts();
    mkchkpts();
    mkvisible();

    /*
    for(int i = 0; i < chkpts.size(); i++) {
            if(!visible_seg[7][i])
                    cout << chkpts[i].x << "," << chkpts[i].y << " " <<
    chkpts[i+1].x << "," << chkpts[i+1].y << endl;
    }

    for(int i = 0; i < visible_seg.size(); i++) {
            for(int j = 0; j < chkpts.size(); j++) {
                    cout << visible_seg[i][j];
            }
            cout << endl;
            for(int j = 0; j < chkpts.size(); j++) {
                    cout << visible_pts[i][j];
            }
            cout << endl << endl;
    }
    // */

    cout << solve() << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

#define EPS 1e-9
#define x first
#define y second
#define mkp make_pair

typedef pair<double, double> pdd;

vector<pdd> polygon;
vector<vector<pdd>> pts;
vector<pdd> chkpts;
vector<bitset<100>> visible_pts;
vector<bitset<100>> visible_seg;

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

template <class T> T sqr(T x) { return x * x; }

double dist(pdd a, pdd b) {
  pdd c;
  c.x = b.x - a.x;
  c.y = b.y - a.y;
  return sqrt(c.x * c.x + c.y * c.y);
}

bool eq_pt(pdd a, pdd b) { return dist(a, b) < EPS; }

bool on_seg(pdd pt, pdd a, pdd b) {
  pdd c, d;
  c.x = a.x - pt.x;
  c.y = a.y - pt.y;
  d.x = b.x - pt.x;
  d.y = b.y - pt.y;
  return (dot(c, d) < EPS) && (fabs(cross(c, d)) < EPS);
}

bool parallel(pdd li0s, pdd li0t, pdd li1s, pdd li1t) {
  pdd a, b;
  a = mkp(li0t.x - li0s.x, li0t.y - li0s.y);
  b = mkp(li1t.x - li1s.x, li1t.y - li1s.y);
  return fabs(cross(a, b)) < EPS;
}

pdd intersection(pdd li0s, pdd li0t, pdd li1s, pdd li1t) {
  double s, t;
  pdd a, b, c;

  a = mkp(li1s.x - li0s.x, li1s.y - li0s.y);
  b = mkp(li1t.x - li0s.x, li1t.y - li0s.y);
  c = mkp(li0t.x - li0s.x, li0t.y - li0s.y);

  if (fabs(cross(a, b)) < EPS)
    return li0s;

  s = cross(a, c) / cross(a, b);
  t = cross(c, b) / cross(a, b);

  return mkp(li0s.x + c.x / (s + t), li0s.y + c.y / (s + t));
}

void mkpts() {
  pts.resize(polygon.size());
  for (int i = 0; i < polygon.size(); i++) {
    pdd li0s = polygon[i];
    for (int j = 1; j < polygon.size(); j++) {
      pdd li0t = polygon[(i + j) % polygon.size()];
      for (int k = 0; k < polygon.size(); k++) {
        pdd li1s, li1t, res;
        li1s = polygon[k];
        li1t = polygon[(k + 1) % polygon.size()];
        if (parallel(li0s, li0t, li1s, li1t))
          continue;
        res = intersection(li0s, li0t, li1s, li1t);
        if (on_seg(res, li1s, li1t))
          pts[k].push_back(res);
      }
    }
  }
  for (int i = 0; i < polygon.size(); i++)
    pts[i].push_back(polygon[i]);
}

pdd cmpbase;
bool cmp(pdd a, pdd b) { return dist(cmpbase, a) < dist(cmpbase, b); }

void mkchkpts() {
  for (int i = 0; i < pts.size(); i++) {
    cmpbase = polygon[i];
    sort(pts[i].begin(), pts[i].end(), cmp);
  }
  chkpts.push_back(pts[0][0]);
  for (int i = 0; i < pts.size(); i++) {
    for (int j = 0; j < pts[i].size(); j++) {
      if (dist(chkpts.back(), pts[i][j]) > EPS)
        chkpts.push_back(pts[i][j]);
    }
  }
}

bool valid_angle(int indx, pdd p) {
  int sz = polygon.size();

  pdd a, b;
  a = mkp(polygon[indx].x - polygon[(indx - 1 + sz) % sz].x,
          polygon[indx].y - polygon[(indx - 1 + sz) % sz].y);
  b = mkp(polygon[(indx + sz + 1) % sz].x - polygon[indx].x,
          polygon[(indx + sz + 1) % sz].y - polygon[indx].y);

  pdd aa, bb;
  aa = mkp(p.x - polygon[(indx - 1 + sz) % sz].x,
           p.y - polygon[(indx - 1 + sz) % sz].y);
  bb = mkp(p.x - polygon[indx].x, p.y - polygon[indx].y);

  if (cross(a, b) > 0)
    return (cross(a, aa) + EPS > 0) && (cross(b, bb) + EPS > 0);
  else
    return (cross(a, aa) + EPS > 0) || (cross(b, bb) + EPS > 0);
}

bool seen(pdd a, pdd b) {
  pdd c = mkp(b.x - a.x, b.y - a.y);
  if (eq_pt(a, b))
    return true;

  for (int i = 0; i < polygon.size(); i++) {
    pdd seg0s, seg0t;
    seg0s = polygon[i];
    seg0t = polygon[(i + 1) % polygon.size()];
    if (parallel(seg0s, seg0t, a, b))
      continue;
    pdd p = intersection(seg0s, seg0t, a, b);
    if (!on_seg(p, a, b) || eq_pt(p, a) || eq_pt(p, b))
      continue;
    if (!on_seg(p, seg0s, seg0t))
      continue;

    int indx = -1;
    for (int j = 0; j < polygon.size(); j++) {
      if (eq_pt(p, polygon[j])) {
        indx = j;
      }
    }
    if (!(indx + 1))
      return false;

    int sz = polygon.size();
    pdd v, w;
    v = mkp(polygon[(indx - 1 + sz) % sz].x - p.x,
            polygon[(indx - 1 + sz) % sz].y - p.y);
    w = mkp(polygon[(indx + 1) % sz].x - p.x, polygon[(indx + 1) % sz].y - p.y);
    if (cross(v, c) * cross(w, c) + EPS < 0) {
      return false;
    }
    if (!valid_angle(indx, b)) {
      return false;
    }
  }
  return true;
}

void mkvisible() {
  visible_pts.resize(polygon.size());
  visible_seg.resize(polygon.size());
  for (int i = 0; i < visible_pts.size(); i++) {
    visible_pts[i].reset();
    visible_seg[i].reset();
  }
  for (int i = 0; i < polygon.size(); i++) {
    for (int j = 0; j < chkpts.size(); j++) {
      if (valid_angle(i, chkpts[j]))
        visible_pts[i][j] = seen(polygon[i], chkpts[j]);
      else
        visible_pts[i][j] = false;
    }
  }
  for (int i = 0; i < visible_pts.size(); i++) {
    for (int j = 0; j < chkpts.size(); j++) {
      visible_seg[i][j] =
          visible_pts[i][j] && visible_pts[i][(j + 1) % chkpts.size()];
    }
  }
}

int solve() {
  int res, sz;
  res = sz = polygon.size();

  for (int i = 0; i < (1 << sz); i++) {
    bitset<100> bs;
    bs.reset();
    int cnt = 0;
    for (int j = 0; j < sz; j++) {
      if (i & (1 << j)) {
        cnt++;
        for (int k = 0; k < chkpts.size(); k++) {
          if (visible_seg[j][k])
            bs[k] = true;
        }
      }
    }
    bool flg = true;
    for (int j = 0; j < chkpts.size(); j++) {
      flg &= bs[j];
    }
    if (flg) {
      res = min(res, cnt);
    }
  }
  return res;
}

int main() {
  int n;

  while (cin >> n, n) {
    polygon.clear();
    pts.clear();
    chkpts.clear();
    visible_pts.clear();
    visible_seg.clear();

    polygon.resize(n);
    for (int i = 0; i < n; i++) {
      cin >> polygon[i].x >> polygon[i].y;
    }
    mkpts();
    mkchkpts();
    mkvisible();

    /*
    for(int i = 0; i < chkpts.size(); i++) {
            if(!visible_seg[7][i])
                    cout << chkpts[i].x << "," << chkpts[i].y << " " <<
    chkpts[i+1].x << "," << chkpts[i+1].y << endl;
    }

    for(int i = 0; i < visible_seg.size(); i++) {
            for(int j = 0; j < chkpts.size(); j++) {
                    cout << visible_seg[i][j];
            }
            cout << endl;
            for(int j = 0; j < chkpts.size(); j++) {
                    cout << visible_pts[i][j];
            }
            cout << endl << endl;
    }
    // */

    cout << solve() << endl;
  }
}