문제 설명
점 네 개의 좌표를 담은 이차원 배열 dots가 다음과 같이 매개변수로 주어집니다.
- [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
주어진 네 개의 점을 두 개씩 이었을 때, 두 직선이 평행이 되는 경우가 있으면 1을 없으면 0을 return 하도록 solution 함수를 완성해보세요.
제한사항
- dots의 길이 = 4
- dots의 원소는 [x, y] 형태이며 x, y는 정수입니다.
0 ≤ x, y ≤ 100 - 서로 다른 두개 이상의 점이 겹치는 경우는 없습니다.
- 두 직선이 겹치는 경우(일치하는 경우)에도 1을 return 해주세요.
- 임의의 두 점을 이은 직선이 x축 또는 y축과 평행한 경우는 주어지지 않습니다.
입출력 예
dots | result |
[[1, 4], [9, 2], [3, 8], [11, 6]] | 1 |
[[3, 5], [4, 1], [2, 4], [5, 10]] | 0 |
입출력 예 #1 : 점 [1, 4], [3, 8]을 잇고 [9, 2], [11, 6]를 이으면 두 선분은 평행합니다.
입출력 예 #2 : 점을 어떻게 연결해도 평행하지 않습니다.
실패 코드
/*
import java.lang.Math;
class Solution {
public int solution(int[][] dots) {
int caseX1 = Math.abs(dots[0][0] - dots[1][0]);
int caseY1 = Math.abs(dots[0][1] - dots[1][1]);
int case1 = caseY1 / caseX1;
int caseX2 = Math.abs(dots[0][0] - dots[2][0]);
int caseY2 = Math.abs(dots[0][1] - dots[2][1]);
int case2 = caseY2 / caseX2;
int caseX3 = Math.abs(dots[0][0] - dots[3][0]);
int caseY3 = Math.abs(dots[0][1] - dots[3][1]);
int case3 = caseY3 / caseX3;
int caseX4 = Math.abs(dots[1][0] - dots[2][0]);
int caseY4 = Math.abs(dots[1][1] - dots[2][1]);
int case4 = caseY4 / caseX4;
int caseX5 = Math.abs(dots[1][0] - dots[3][0]);
int caseY5 = Math.abs(dots[1][1] - dots[3][1]);
int case5 = caseY5 / caseX5;
int caseX6 = Math.abs(dots[2][0] - dots[3][0]);
int caseY6 = Math.abs(dots[2][1] - dots[3][1]);
int case6 = caseY6 / caseX6;
if(case1 == case2) return 1;
if(case1 == case3) return 1;
if(case1 == case4) return 1;
if(case1 == case5) return 1;
if(case1 == case6) return 1;
if(case2 == case3) return 1;
if(case2 == case4) return 1;
if(case2 == case5) return 1;
if(case2 == case6) return 1;
if(case3 == case4) return 1;
if(case3 == case5) return 1;
if(case3 == case6) return 1;
if(case4 == case5) return 1;
if(case4 == case6) return 1;
if(case5 == case6) return 1;
return 0;
}
}
*/
코드의 문제점
- 절댓값으로 기울기 구하기 → 방향성 무시
예를 들어 (3,5)와 (4,1)의 기울기를 계산한다고 해보자.
올바른 기울기: (1 - 5) / (4 - 3) = -4 / 1 = -4
너의 코드: abs(1 - 5) / abs(4 - 3) = 4 / 1 = 4
즉, 기울기가 -4인데도 +4로 계산됨 → 기울기 비교가 부정확함
이로 인해, 실제로는 평행하지 않은 선분들이 기울기가 같다고 잘못 판단됨. - 정수 나눗셈 (int / int)으로 기울기 소수점 정보 손실
예를 들어 (2, 4)와 (5, 10)을 비교하면:
기울기: (10 - 4) / (5 - 2) = 6 / 3 = 2.0
하지만, 만약 (5,10)과 (4,1)처럼 (10 - 1)/(5 - 4) = 9 / 1 = 9라면, 분모가 작을수록 값이 커지게 되므로,
정수값으로만 기울기를 판단하면 잘못된 결과가 나올 수 있음
풀이1
class Solution {
public int solution(int[][] dots) {
float[] tmp = new float[6];
int answer = 0;
tmp[0] = (float) (dots[0][1] - dots[1][1]) / (dots[0][0] -dots[1][0]);
tmp[1] = (float) (dots[0][1] - dots[2][1]) / (dots[0][0] -dots[2][0]);
tmp[2] = (float) (dots[0][1] - dots[3][1]) / (dots[0][0] -dots[3][0]);
tmp[3] = (float) (dots[1][1] - dots[2][1]) / (dots[1][0] -dots[2][0]);
tmp[4] = (float) (dots[1][1] - dots[3][1]) / (dots[1][0] -dots[3][0]);
tmp[5] = (float) (dots[2][1] - dots[3][1]) / (dots[2][0] -dots[3][0]);
for (int i = 0; i < 6; i++) {
for (int j = i+1; j < 6; j++) {
if (tmp[i] == tmp[j]) {
answer =1;
}
}
}
return answer;
}
}
풀이2
class Solution {
int[][] dots;
public int solution(int[][] dots) {
this.dots = dots;
if (parallel(0, 1, 2, 3)) return 1;
if (parallel(0, 2, 1, 3)) return 1;
if (parallel(0, 3, 1, 2)) return 1;
return 0;
}
boolean parallel(int a, int b, int c, int d) {
int x = (dots[a][0] - dots[b][0]) * (dots[c][1] - dots[d][1]);
int y = (dots[a][1] - dots[b][1]) * (dots[c][0] - dots[d][0]);
return x == y || x == -y;
}
}
왜 세 가지 조합만 비교하면 되는가?
총 네 개의 점이 주어졌을 때, 가능한 선분의 조합은 총 6개지만,
서로 다른 두 선분이 평행한 경우만 찾으면 되기 때문에,
선분 2개를 뽑는 조합(4C2 = 6개) 중, 평행한 두 쌍이 될 수 있는 조합은 단 3가지뿐
네 개의 점이 있다고 하자:
A = dots[0]
B = dots[1]
C = dots[2]
D = dots[3]
세 가지 가능한 "두 쌍의 선분 조합"은:
A-B 와 C-D
A-C 와 B-D
A-D 와 B-C
이 조합 외에는 두 쌍의 선이 완전히 분리되지 않거나 중복돼서 비교할 필요가 없어.
곱셈으로 교차 비교하는 이유
기울기 m = (y2 - y1) / (x2 - x1) 이지만, 나눗셈을 사용하면:
- 0으로 나눌 위험
- 소수점 비교 시 오차 발생
그래서 대신 사용하는 방식:
(y2 - y1) * (x4 - x3) == (y4 - y3) * (x2 - x1)
→ 두 기울기가 같으면 양변이 같음
이렇게 하면 정수 계산으로도 정확하게 기울기 일치 여부를 알 수 있다.
'👨💻 Coding Test > Programers' 카테고리의 다른 글
[Programmers/Java/Lv.0/수학 유형] 64.유한소수 판별하기 (0) | 2025.03.24 |
---|---|
[Programmers/Java/Lv.0/수학 유형] 63.겹치는 선분의 길이 (0) | 2025.03.23 |
[Programmers/Java/Lv.0/수학 유형] 61.저주의 숫자 3 (0) | 2025.03.15 |
[Programmers/Java/Lv.0/문자열 유형] 60.외계어 사전 (0) | 2025.03.14 |
[Programmers/Java/Lv.0/수학 유형] 59.삼각형의 완성조건 (2) (0) | 2025.03.14 |