본문 바로가기

코딩 테스트/백준

[백준 1485번 문제, Python3] 정사각형

728x90
반응형

문제

문제

네 점이 주어졌을 때, 네 점을 이용해 정사각형을 만들 수 있는지 없는지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 네 줄로 이루어져 있으며, 점의 좌표가 한 줄에 하나씩 주어진다. 점의 좌표는 -100,000보다 크거나 같고, 100,000보다 작거나 같은 정수이다. 같은 점이 두 번 이상 주어지지 않는다.


코드

import math


class Line:
    x1, y1, x2, y2 = 0, 0, 0, 0
    length = 0

    def __init__(self, a, b):
        self.x1 = a[0]
        self.y1 = a[1]
        self.x2 = b[0]
        self.y2 = b[1]
        self.length = math.sqrt((self.x1 - self.x2) ** 2 + (self.y1 - self.y2) ** 2)    # d = √((x2-x1)² + (y2-y1)²)

    def __lt__(self, other):
        return self.length < other.length    # 비교를 위한 메서드 재정의

    def slope(self):
        return (self.y2 - self.y1) / (self.x2 - self.x1)    # 기울기 반환 메서드


count = int(input())
input_list = []
for i in range(count * 4):
    tmp = list(map(int, input().split(" ")))
    input_list.append(tmp)  # input_list = [[1, 1], [1, 2], [2, 1], [2, 2], [2, 2], [3, 3], [4, 4], [5, 5]]

for i in range(0, count):
    tmp = input_list[i * 4:(i + 1) * 4]  # [[1, 1], [1, 2], [2, 1], [2, 2]] 각 점을 저장하는 리스트
    tmp2 = []    # 각 점을 이은 선분을 저장하는 리스트
    for index, value in enumerate(tmp):
        for k in range(index + 1, len(tmp)):
            tmp2.append(Line(value, tmp[k]))

    tmp2 = sorted(tmp2, reverse=True)  # 무조건 tmp2[0], tmp2[1] 대각선 객체

    # 대각선으로 정사각형인지 체크
    try:
        # 두 선분이 교차하는 각을 계산해야함
        # 그러나 두 선분의 기울기를 빼면 0이 나올 때가 있음
        theta = math.degrees(
            math.atan(abs((tmp2[1].slope() - tmp2[0].slope()) / (1 + tmp2[0].slope() * tmp2[1].slope()))))
        if theta == 90:    # 만약 두 선분이 교차하는 각이 90도이면 정사각형이다
            print(1)
        else:
            print(0)

    except:    # 두 점의 기울기가 같은 경우 ZeroDivisionError 에러가 생긴다
        if tmp2[1].length == tmp2[0].length:
            print(1)    # 두 선분의 절대값 기울기가 같은 경우 수직선이다. 이 때 두 선분의 길이가 같으면 정사각형.
        else:
            print(0)

해결

각 점이 있으면 두 점의 길이를 각각 구하고 큰 순서대로 정렬하면 가장 앞과 두번째가 대각선 길이가 될것이다
두 대각선이 교차하는 각이 90도이면 정사각형이라고 생각해서 저렇게 풀었다
 

# 두 직선이 이루는 각 계산
theta = math.degrees(math.atan(abs((m2-m1)/(1+m1*m2))))

 
두 직선이 이루는 각은 위 공식으로 구하는데
0을 나누는 경우가 생긴다 그래서 예외 처리를하고 길이가 같으면 1로 처리한다


참고

https://kldp.org/node/126284

정사각형 판별 문제입니다. | KLDP

네개의 점(w,x,y,z)의 좌표(x,y)가 주어졌을 때, 이 점들을 이은 도형이 정사각형인지 판펼하는 소스를 C언어로 작성하라는 문제인데.... 아 생각보다 엄청 어렵네요;; 정사각형의 수학적 정의, 4변이

kldp.org

 
 
 

728x90
반응형