Language: C++

#include <fstream>
#include <iostream>
#include <vector>
#include <complex>
#include <cmath>
#include <cstring>

using namespace std;

typedef complex<int> P;
typedef pair<P, P> L;

int root[1000];

int cross(P a, P b) { return imag(conj(a)*b); }

bool onLP(L l, P p){
	double d1 = sqrt((double)norm(l.first-p))+sqrt((double)norm(p-l.second));
	double d2 = sqrt((double)norm(l.first-l.second));
	return abs(d1-d2) < 1e-8;
}

bool touchLP(L l, P p){
	return (l.first == p || l.second == p);
}

bool onLL(L l, L m){
	return (onLP(l,m.first)||onLP(l,m.second)||onLP(m,l.first)||onLP(m,l.second));
}

bool touchLL(L l, L m){
	return (touchLP(l, m.first)||touchLP(l, m.second));
}

int getRoot(int v){
	return root[v]==-1 ? v : root[v] = getRoot(root[v]);
}

int main(){
	int n;
	while(cin >> n, n){
		vector<L> vL;
		for(int i=0;i<n;i++){
			int xa, ya, xb, yb;
			cin >> xa >> ya >> xb >> yb;
			vL.push_back(make_pair(P(xa,ya),P(xb,yb)));
		}
		memset(root, -1, sizeof(root));
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				if(onLL(vL[i], vL[j])){
					int p = getRoot(i), q = getRoot(j);
					if(p!=q) root[q] = p;
				}
			}
		}
		int ans[10] = {};
		for(int i=0;i<n;i++){
			vector<L> lines;
			for(int j=0;j<n;j++)
				if(getRoot(j)==i) lines.push_back(vL[j]);
			if(lines.size() == 0) continue;
			else if(lines.size() == 1) ans[1]++;
			else if(lines.size() == 3){
				bool flag = true;
				for(int i=0;i<3;i++){
					bool check = false;
					for(int j=0;j<3;j++){
						if(i==j) continue;
						check |= touchLL(lines[i], lines[j]);
					}
					flag &= check;
				}
				flag ? ans[7]++ : ans[4]++;
			}
			else if(lines.size() == 4){
				vector<P> point;
				for(int i=0;i<4;i++){
					bool check = true;
					for(int j=0;j<point.size();j++)
						if(point[j] == lines[i].first) check = false;
					if(check) point.push_back(lines[i].first);
					check = true;
					for(int j=0;j<point.size();j++)
						if(point[j] == lines[i].second) check = false;
					if(check) point.push_back(lines[i].second);
				}
				if(point.size() == 4) ans[0]++;
				if(point.size() == 5) ans[9]++;
				if(point.size() == 6) ans[3]++;
			}
			else if(lines.size() == 5){
				vector<P> point;
				vector<bool> use(5,false);
				point.push_back(lines[0].first);
				point.push_back(lines[0].second);
				use[0] = true;
				while(true){
					bool end = true;
					for(int i=0;i<5;i++){
						if(use[i]) continue;
						if(touchLP(lines[i], point.back())){
							if(lines[i].first == point.back())
								point.push_back(lines[i].second);
							else
								point.push_back(lines[i].first);
							use[i] = true, end = false;
							continue;
						}
						if(touchLP(lines[i], point[0])){
							reverse(point.begin(), point.end());
							if(lines[i].first == point.back())
								point.push_back(lines[i].second);
							else
								point.push_back(lines[i].first);
							use[i] = true, end = false;
						}
					}
					if(end) break;
				}
				if(point.size() != 6) { ans[8]++; continue; }
				if(onLP(make_pair(point[1],point[2]), point.back())||
					onLP(make_pair(point[3],point[4]), point[0]))
				{ ans[6]++; continue; }
				cross(point[1]-point[0], point[2]-point[1]) > 0 ? ans[5]++ : ans[2]++;
			}
		}
		printf("%d", ans[0]);
		for(int i=1;i<10;i++) printf(" %d", ans[i]);
		printf("\n");
	}
}

Compiler output:
a.cc: In function 'int main()':
a.cc:111:57: error: 'reverse' was not declared in this scope
  111 |                                                         reverse(point.begin(), point.end());
      |                                                         ^~~~~~~