Example #1
0
  public void run() {
    int n = in.nextInt();
    Curve[] curves = new Curve[n];
    Point s = new Point(2 * 0 + 1, 2 * 0 + 1), t = new Point(2 * 100000 + 1, 2 * 0 + 1);
    for (int i = 0; i < n; ++i) {
      curves[i] = new Curve();
      curves[i].h = in.nextInt();
      curves[i].p = new Point[in.nextInt()];
      for (int j = 0; j < curves[i].p.length; ++j)
        curves[i].p[j] = new Point(2 * in.nextInt(), 2 * in.nextInt());
    }

    List<Intersection> intersections = new ArrayList<Intersection>();
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < curves[i].p.length; ++j) {
        Point a = s, b = t, c = curves[i].p[j], d = curves[i].p[(j + 1) % curves[i].p.length];
        long den = d.min(c).cross(b.min(a));
        if (den == 0) {
          boolean res = a.onseg(c, d) || b.onseg(c, d) || c.onseg(a, b) || d.onseg(a, b);
          if (res) throw new RuntimeException("point in common on parallel lines");
        } else {
          long num1 = d.min(c).cross(c.min(a));
          long num2 = a.min(c).cross(b.min(a));
          if (den < 0) {
            den = -den;
            num1 = -num1;
            num2 = -num2;
          }
          if (0 == num1 || num1 == den || 0 == num2 || num2 == den)
            throw new RuntimeException("segments touch");
          if (0 <= num1 && num1 <= den && 0 <= num2 && num2 <= den) {
            intersections.add(new Intersection(num1, den, i));
          }
        }
      }
    Collections.sort(intersections);

    int[] last = new int[n], cnt = new int[n];
    for (int i = 0; i < n; ++i) last[i] = -1;
    for (int i = 0; i < intersections.size(); ++i) {
      int cur = intersections.get(i).curve;
      last[cur] = i;
      cnt[cur]++;
    }

    int up = 0, down = 0, at = 0, now = -1;
    while (at < intersections.size()) {
      int cur = intersections.get(at).curve;
      if (cnt[cur] % 2 == 0) {
        at = last[cur] + 1;
      } else {
        int next = curves[cur].h;
        if (now != -1) {
          if (now < next) up += next - now;
          else down += now - next;
        }
        now = next;
        at = last[cur] + 1;
      }
    }

    System.out.println(up + " " + down);
  }