Problem:
Problem D: Area Separation

Mr. Yamada Springfield Tanaka は、国家区画整理事業局局長補佐代理という大任を任されていた。
現在、彼の国は大規模な区画整理の最中であり、この区画整理をスムーズに終わらせることができたならば彼の昇進は間違いなしであるとされている。

ところが、そんな彼の出世を快く思わない者も多くいるのだ。 そんな人間の 1 人に、Mr.Sato Seabreeze Suzuki がいた。
彼は、ことあるごとに Mr. Yamada の足を引っ張ろうと画策してきた。 今回も Mr. Sato は足を引っ張るために、実際の区画整理を担当している組織に圧力をかけて、区画整理の結果を非常に分かりにくいものにしてしまった。

そのため、Mr. Yamada に渡された結果は、 ある正方形の土地をどの直線で分割したかという情報のみになっていた。
最低限、その正方形の土地がいくつに分割されたかだけでも分からなければ、Mr. Yamada は昇進どころか解雇されること間違いなしである。

あなたの仕事は、(-100,-100)、(100,-100)、(100,100)、(-100,100) を頂点とする正方形領域が、与えられた n 本の直線によっていくつに分割されているかを調べるプログラムを書いて、Mr. Yamada を解雇の危機から救うことである。

Input

入力は複数のテストケースからなる。

それぞれのテストケースの最初の行では、直線数を表す整数 n が与えられる（1 <= n <= 100）。 その後の n 行にはそれぞれ 4 つの整数 x1 、y1 、 x2 、y2 が含まれる。
これらの整数は直線上の相異なる 2 点 (x1 , y1 ) と (x2 , y2 ) を表す。
与えられる 2 点は常に正方形の辺上の点であることが保証されている。 与えられる n 本の直線は互いに異なり、直線同士が重なることはない。 また、直線が正方形の辺と重なることもない。

入力の終了は n = 0 で表される。

Output

それぞれのテストケースについて、n 本の直線によって分割された領域の数を 1 行で出力せよ。

なお、距離が 10-10 未満の 2 点は一致するとみなしてよい。 また、|PQ| < 10-10、|QR| < 10-10 でかつ |PR| >= 10-10となるような交点の組 P、Q、R は存在しない。

Sample Input

2
-100 -20 100 20
-20 -100 20 100
2
-100 -20 -20 -100
20 100 100 20
0

Output for the Sample Input

4
3

Solution in C++11 (judge verdict: Wrong Answer)

#include <cassert>
#include <array>
#include <algorithm>
#include <iostream>
#include <complex>
#include <vector>
#include <set>
using namespace std;

const double EPS = 1e-10;
template<class T>
bool eq(const T& a, const T& b) {return abs(a - b) < EPS;}

typedef complex<double> point;

namespace std {
	bool operator==(const point &a, const point &b){
		return eq(abs(a - b), 0.);
	}
	bool operator!=(const point &a, const point &b){
		return !eq(abs(a - b), 0.);
	}
	bool operator<(const point& a, const point& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}

double cross(const point& a, const point& b) {
	return imag(conj(a)*b);
}
double dot(const point& a, const point& b) {
	return real(conj(a)*b);
}

typedef array<point, 2> line;

bool intersectLL(const line& l, const line& m) {
	return !eq(cross(l[1]-l[0], m[1]-m[0]), 0.) || // non-parallel
			eq(cross(l[1]-l[0], m[0]-l[0]), 0.);   // same line
}

point crosspoint(const line& l, const line& m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (eq(A, 0.) && eq(B, 0.)) return m[0]; // same line
	if (eq(A, 0.)) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

vector<line> lines;

int hitCount(const line& s) {
	set<point> hits;
	for (const auto& t : lines) {
		if (intersectLL(s, t)) {
			point p = crosspoint(s, t);
			if (-100 < p.real() && p.real() < 100 && -100 < p.imag() && p.imag() < 100) {
				hits.insert(p);
			}
		}
	}
	return hits.size();
}

int main() {
	int n;
	while (cin >> n, n) {
		int cnt = 1;
		lines.clear();
		for (int i = 0; i < n; i++) {
			line l;
			for (auto& p : l) {
				int x, y;
				cin >> x >> y;
				p = point(x, y);
			}
			cnt += hitCount(l) + 1;
			lines.push_back(l);
		}
		cout << cnt << endl;
	}
	return 0;
}