SRM 668 Div2 Medium IsItASquare
TopCoder Statistics - Problem Statement
- 本番では自作の points class みたなのでごちゃごちゃやっていた。
- 絶対もっと簡単に書けるだろうなと思っていたらTopCoder SRM 668 Div2 Medium IsItASquare - kmjp's blogとかみつけたので参照にしてコードを書いてみた。
class IsItASquare { public: string isSquare(vector <int> x, vector <int> y) { set<pair<int,int>> S; REP(i,4) S.emplace(x[i],y[i]); FOR(i,1,4) { // ベクトル X = x[0]x[i] を一つ定める int dx = x[i]-x[0]; int dy = y[i]-y[0]; // そのベクトルを 90 度回転させた位置(x0+X,xi+X それぞれ)に残りの点があればよい // 全ベクトルを総当りするので -90 度回転は考えなくてよい。 if (S.count({x[0]-dy,y[0]+dx}) == 0) continue; if (S.count({x[i]-dy,y[i]+dx}) == 0) continue; return "It's a square"; } return "Not a square"; } };
- arena では長さに注目した解答もあった。
- 以下はそのコードを参照にしてみたもの。
class IsItASquare { public: int sqr(int x, int y) { return x*x + y*y; } bool check(const vector<int> &dist) { assert(dist.size()==6);// 対角線を含め 6 本の辺 // dist は長さ順でソート済みなので、正方形なら最初の 4 つは長さが同じはず REP(i,4) { if (dist[i] != dist[0]) return false; } // 正方形なら対角線の長さは同じはず if (dist[4] != dist[5]) return false; // 対角線の長さと各辺の長さの関係をチェック return (dist[0]*2==dist[4]); } string isSquare(vector <int> x, vector <int> y) { vector<int> dist; REP(i,4) FOR(j,i+1,4) { // 各点の距離の二乗を入れる dist.push_back(sqr(x[i]-x[j],y[i]-y[j])); } sort(RANGE(dist)); if (check(dist)) return "It's a square"; else return "Not a square"; } };