문제 설명
Ax + By + C = 0으로 표현할 수 있는 n개의 직선이 주어질 때, 이 직선의 교점 중 정수 좌표에 별을 그리려 합니다.
예를 들어, 다음과 같은 직선 5개를
- 2x - y + 4 = 0
- -2x - y + 4 = 0
- -y + 1 = 0
- 5x - 8y - 12 = 0
- 5x + 8y + 12 = 0
좌표 평면 위에 그리면 아래 그림과 같습니다.
이때, 모든 교점의 좌표는 (4, 1), (4, -4), (-4, -4), (-4, 1), (0, 4), (1.5, 1.0), (2.1, -0.19), (0, -1.5), (-2.1, -0.19), (-1.5, 1.0)입니다. 이 중 정수로만 표현되는 좌표는 (4, 1), (4, -4), (-4, -4), (-4, 1), (0, 4)입니다.
만약 정수로 표현되는 교점에 별을 그리면 다음과 같습니다.
위의 그림을 문자열로 나타낼 때, 별이 그려진 부분은 *, 빈 공간(격자선이 교차하는 지점)은 .으로 표현하면 다음과 같습니다.
"..........."
".....*....."
"..........."
"..........."
".*.......*."
"..........."
"..........."
"..........."
"..........."
".*.......*."
"..........."
이때 격자판은 무한히 넓으니 모든 별을 포함하는 최소한의 크기만 나타내면 됩니다.
따라서 정답은
"....*...."
"........."
"........."
"*.......*"
"........."
"........."
"........."
"........."
"*.......*"
입니다.
직선 A, B, C에 대한 정보가 담긴 배열 line이 매개변수로 주어집니다. 이때 모든 별을 포함하는 최소 사각형을 return 하도록 solution 함수를 완성해주세요.
제한사항
- line의 세로(행) 길이는 2 이상 1,000 이하인 자연수입니다.
- line의 가로(열) 길이는 3입니다.
- line의 각 원소는 [A, B, C] 형태입니다.
- A, B, C는 -100,000 이상 100,000 이하인 정수입니다.
- 무수히 많은 교점이 생기는 직선 쌍은 주어지지 않습니다.
- A = 0이면서 B = 0인 경우는 주어지지 않습니다.
- 정답은 1,000 * 1,000 크기 이내에서 표현됩니다.
- 별이 한 개 이상 그려지는 입력만 주어집니다.
입출력 예
line | result |
[[2, -1, 4], [-2, -1, 4], [0, -1, 1], [5, -8, -12], [5, 8, 12]] | ["....*....", ".........", ".........", "*.......*", ".........", ".........", ".........", ".........", "*.......*"] |
[[0, 1, -1], [1, 0, -1], [1, 0, 1]] | ["*.*"] |
[[1, -1, 0], [2, -1, 0]] | ["*"] |
[[1, -1, 0], [2, -1, 0], [4, -1, 0]] | ["*"] |
코드 설명
문제에 주어진 공식에 따라 직선과 직선이 만나는 교점을 구합니다. 이때 x와 y 좌표는 실수형이므로 1.0으로 나누었을 때 나누어 떨어지는 즉, 정수 좌표만 구해 stars 배열에 저장합니다.
이후 x와 y의 최소-최대 범위를 구하고 해당 범위를 점으로 나타낸 배열 coord를 선언했습니다. 그리고 반복문을 통해 교점에 해당하는 점은 별로 바꾸어줍니다.
def solution(line):
stars = []
answer = []
x_max = y_max = -int(1e15)
x_min = y_min = int(1e15)
# 교점 구하기
for i in range(len(line)) :
a,b,e = line[i]
for j in range(i+1, len(line)) :
c,d,f = line[j]
if(a*d - b*c != 0) :
x = (b*f - e*d) / (a*d - b*c)
y = (e*c - a*f) / (a*d - b*c)
# 교점 중 정수 쌍만 구하기
if(x % 1.0 == 0 and y % 1.0 == 0) :
x = int(x)
y = int(y)
stars.append([x,y])
# 교점이 있는 x와 y의 최소 범위 ~ 최대 범위 구하기
if(x_min > x) : x_min = x
if(y_min > y) : y_min = y
if(x_max < x) : x_max = x
if(y_max < y) : y_max = y
# 해당 범위만큼 점 찍기
x_len = x_max - x_min + 1
y_len = y_max - y_min + 1
coord = [['.'] * x_len for _ in range(y_len)]
# 교점에 해당하는 점은 별로 바꾸기
for star_x, star_y in stars :
nx = star_x + abs(x_min) if x_min < 0 else star_x - x_min
ny = star_y + abs(y_min) if y_min < 0 else star_y - y_min
coord[ny][nx] = "*"
for result in coord : answer.append(''.join(result))
# answer을 거꾸로 리턴
return answer[::-1]
'알고리즘 공부' 카테고리의 다른 글
[프로그래머스] 삼각 달팽이 - 파이썬(Python) (0) | 2023.08.08 |
---|---|
[프로그래머스] 행렬 테두리 회전하기 - 파이썬(Python) (0) | 2023.08.07 |
[프로그래머스] 시소 짝궁 자바(Java) (0) | 2023.08.03 |
[프로그래머스] 롤케이크 자르기 자바(Java) (0) | 2023.08.02 |
[프로그래머스] 연속 부분 수열 합의 개수 자바(Java) (0) | 2023.08.01 |