[ 백준 ] 1485 / 정사각형

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
31/228
post-thumbnail

# Appreciation

/*
 * Problem :: 1485 / 정사각형
 *
 * Kind :: Math
 *
 * Insight
 * - 일단 주어지는 점들을 정렬해서 순서를 매겨야 한다
 *   시계방향으로 읽든, 반시계방향으로 읽든
 *   어떤 좌표들이 주어지더라도 일정한 규칙에 맞춰 일관되게 읽어야만
 *   그 점의 순서에 따라 도형을 만들 수 있기 때문이다
 *   + 본인의 경우 (x,y) 좌표 기준 오름차순으로 정렬하였다
 *     이 경우,
 *
 *     #  #   1   3
 *
 *     #  #   0   2
 *
 *     위처럼 0-1-2-3 순서로 좌표를 생각할 수 있다
 *     여기서는 0-1, 0-2, 1-3, 2-3 을 연결해서
 *     사각형을 만든다고 생각했다
 *     # 마름모가 되려면
 *       dist(0-1), dist(0-2), dist(1-3), dist(2-3) 이 같아야 한다
 *       -> 정사각형이 되려면
 *          마름모에다가 dist(0-3), dist(1-2)가 같아야 한다
 *
 * Point
 * - 같은 점이 두 번 이상 주어지지 않는다
 *   + 무조건 사각형을 만들 수 있다
 *     # 사각형이 만들어지지 않는 예외에 관해서는
 *       생각하지 않아도 된다
 *
 * - 굳이 sqrt 를 사용해서 오차의 위험성이 있는 double 자료형을 활용하지 않았다
 *   대신, 정수 자료형으로 표현가능한 좌표간의 거리의 제곱을 비교하며
 *   두 좌표간의 거리를 비교하였다
 *   + max(dy,dx)=2*10^5 이므로
 *     max(dy*dy + dx*dx)=8*10^10 이다
 *     int 자료형에서는 Overflow 가 일어나니
 *     long 자료형을 사용해주자
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define endl '\n'

// Set up : Global Variables
struct Point { int x, y; };

// Set up : Functions Declaration
long dist(Point &u, Point &v);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int T; cin >> T;

    while (T--) {
        Point P[4];
        for (auto &p : P)
            cin >> p.x >> p.y;

        // Process
        sort(P, P+4, [](Point &u, Point &v){
            return make_pair(u.x, u.y) < make_pair(v.x, v.y);
        }); /* 좌표 정렬 */

        long d01 = dist(P[0], P[1]); /* dist(0-1) */
        long d02 = dist(P[0], P[2]); /* dist(0-2) */
        long d13 = dist(P[1], P[3]); /* dist(1-3) */
        long d23 = dist(P[2], P[3]); /* dist(2-3) */
        long d03 = dist(P[0], P[3]); /* dist(0-3) */
        long d12 = dist(P[1], P[2]); /* dist(1-2) */

        bool isSquare = (d01 == d02) &&
                        (d13 == d23) &&
                        (d01 == d13) &&
                        (d03 == d12);

        // Control : Output
        cout << ((isSquare) ? 1 : 0) << endl;
    }
}

// Helper Functions
long dist(Point &u, Point &v)
/* 주어진 두 좌표간의 거리의 제곱을 반환 */
{
    long dx = v.x - u.x;
    long dy = v.y - u.y;
    return dx*dx + dy*dy;
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글