SRM312 div2 difficult

とりあえず、2点がA,BがLにたいして線対称のときの条件としては、

ABの中点CがL上にある。
ABとLが直行する。

一番目の条件から、直線を導き、2番目が成り立てば、求めたい直線が得られるというわけ。

注意したいこと。
C(0, 0)になるとき -->AorBを90度回転させよう。(x, y) ->(-y, x)
ABの傾きが無限大のときとか、0のときに注意。
//うーん、がんばったけどわからん。保留にしとこ。
bool is_orthogonal(int x0, int y0, int x1, int y1) {
	return (x0*x1+y0*y1) == 0;
}

bool is_line(int x0, int y0, int x1, int y1) {
	return (y0*x1-y1*x0) == 0;
}

int gcd(int a, int b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd(b, a % b);  //b > a % b
}

class PizzaDivision {
public:
  int howMany(vector <string> toppings) {
    int sz = toppings.size();
    if(sz == 1) {
      return (toppings[0] == "0 0") ? -1 : 1;
    }
    vector<int> x(sz); vector<int> y(sz);
    for(int i = 0; i < sz; i++) {
      sscanf(toppings[i].c_str(), "%d %d", &x[i], &y[i]);
    }
		
		set<pii> line;
    for(int i = 0; i < sz; i++) {
			for(int j = i; j < sz; j++) {
				if(i == j && x[i] == 0 && y[i] == 0) continue;
				dot n(x[i]+x[j], y[i]+y[j]); //line 2 points (0, 0)and(x[i]+x[j], y[i]+y[j])
				if(n.X == 0 && n.Y == 0) {
					n.X = -y[i]; n.Y = x[i];
				}
				if(is_orthogonal(n.X, n.Y, x[i]-x[j], y[i]-y[j]) ) {
					int k;
					for(k = 0; k < sz; k++) {
						bool flag = false;
						for(int d = 0; d < sz; d++) {
							if(is_orthogonal(n.X, n.Y, x[k]-x[d], y[k]-y[d]) && is_line(n.X, n.Y, x[k]+x[d], x[k]+x[d]) ) {
								flag = true; break;
							}
						}
						if(!flag) break;
					}

					if(k == sz) {
						if(n.X == 0) n.Y = 1;
						else if(n.Y == 0) n.X = 1;
						else {
							int sgn = 1;
							int mod = 1;
							if(n.X * n.Y < 0) sgn = -1;
							n.X = abs(n.X); n.Y = abs(n.Y);
							mod = gcd(n.X, n.Y );
							n.X = sgn*(n.X/mod); n.Y /= mod; 
						}
						line.insert(dot(n.X, n.Y) );
					} //end if
				} 
				
			}
		} //end for i
		return line.size();
	}
};