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(); } };