728x90
⬛ 프로그래머스(위클리) | LV.2 교점에 별 만들기 - 구현 문풀 (Java)
https://school.programmers.co.kr/learn/courses/30/lessons/87377
💚문제 접근 방식
- 주어진 직선 정보와 두 직선의 교점 구하는 공식을 활용해서 모든 두 직선 간의 교점을 차례로 구하되, 그 중 (정수로 표현되는) 교점에 한해서 담고, 끝없이 펼쳐진 좌표평면 중 교점을 표현할 정도의 크기로만 잘라서 출력하라는 문제였다.
[주의] long 타입으로 선언한 이유는 A, B, C 각각 (-10^5 ~ 10^5)까지 들어올 수 있는데, 교점 구하는 공식에서 얘들끼리 곱하면 int형 범위를 넘어설 수 있기 때문이다.
1) 입력으로 들어온 line에 대해 이중for문을 돌면서 모든 직선에 대하여 두 직선씩 교점을 구하고자 시도한다.
2) 문제에서 주어진 교점 공식을 구하기 위해 공통 분모와 각 분자를 구하고 교점공식 대입하여 (정수 교점) list 담음
이때 분모가 0인 경우는 (기울기 같아서 교점X)이므로 분모가 0이 아닌 경우에 한해서 (정수로 표현가능한) 교점만 list에 담는다.
(이와 동시에 min, max 양 끝단의 x, y 좌표 각각을 갱신하며 구해둔다.)
3) boolean[][] 에서 max-min+1 로 표현될 좌표평면 크기 지정하고, * 찍을 값에만 true처리를 할 거다.
4) StringBuilder에 flag값 true, false 조건 나눠서 교점에만 * 찍고 answer를 세팅한다.
💚 제출 코드
import java.util.*;
class Solution {
public String[] solution(int[][] line) {
String[] answer = {};
List<long[]> list = new ArrayList<>();
long minX = Long.MAX_VALUE;
long maxX = Long.MIN_VALUE;
long minY = Long.MAX_VALUE;
long maxY = Long.MIN_VALUE;
//인접한 두 직선에 대한 교점 좌표 구하기
for(int i=0; i<line.length; i++){
long a = line[i][0];
long b = line[i][1];
long e = line[i][2];
for(int j=i+1; j<line.length; j++){
long c = line[j][0];
long d = line[j][1];
long f = line[j][2];
//분자 각각 구하고, 공통 분모 구하기
long curDown = a*d - b*c;
long xUp = b*f - e*d;
long yUp = e*c - a*f;
//분모가 0인 경우 두 직선 기울기 평행이라 (교점X)
if(curDown != 0){
double x = xUp / (double) curDown;
double y = yUp / (double) curDown;
if(x == Math.ceil(x) && y == Math.ceil(y)){ //즉, 정수로 표현되는 좌표에 한해서
list.add(new long[] {(long) x, (long) y});
//좌표 경계 양끝단 구할 용도
minX = Math.min(minX, (long)x);
maxX = Math.max(maxX, (long)x);
minY = Math.min(minY, (long)y);
maxY = Math.max(maxY, (long)y );
}
}
}
}
//list에는 정수표현된 교점 좌표만 담긴 상태
//-> boolean[][] 에 교점 찍히는 부분만 true 처리
int N = (int) (maxY - minY + 1);
int M = (int) (maxX - minX + 1);
boolean[][] flag = new boolean[N][M];
for(long[] points : list){
int x = (int) (points[0] - minX);//좌표 재정돈
int y = (int) (points[1] - maxY);
flag[Math.abs(y)][Math.abs(x)] = true;
}
answer = new String[flag.length];
int i = 0;
for(boolean[] t : flag){
StringBuilder sb = new StringBuilder();
for(boolean s : t){
if(s==true){
sb.append("*");
}else{
sb.append(".");
}
}
answer[i] = sb.toString();
i++;
}
return answer;
}
}
💚회고
전반적인 로직의 구성은 의외로 단순하지만, 완벽히 내 힘으로 풀지는 못해서 아쉽다.
728x90
'코딩 테스트 [준비] > [문풀] 프로그래머스_문풀_조지기' 카테고리의 다른 글
프로그래머스 | LV.1 둘만의 암호 - 문자열 구현 문풀 (Java) (16) | 2024.03.02 |
---|---|
프로그래머스 | LV.3 110 옮기기 - 문자열 구현 & Stack 활용 문풀 (Java) (21) | 2024.02.28 |
프로그래머스 | LV.2 혼자 놀기의 달인 - DFS 문풀 (Java) (20) | 2024.02.28 |
프로그래머스 | LV.1 공원 산책 - 단순 구현 문풀 (Java) (26) | 2024.02.28 |
프로그래머스 | LV.3 인사고과 - 단순 구현 문풀 (Java) (21) | 2024.02.25 |