Lewis's Tech Keep

[프로그래머스][JAVA] 당구 연습 본문

Java/알고리즘

[프로그래머스][JAVA] 당구 연습

Lewis Seo 2024. 7. 29. 05:28

링크

https://school.programmers.co.kr/learn/courses/30/lessons/169198

 

 

설명

입사각 반사각이 같다면 어떤 벽을 기준으로 대칭했을 때 직선이 되는 성질이 있다.

아래 그림

 

문제는 당구 벽이기 때문에 각 벽은 4개가 존재한다.

4개의 대칭을 한 예를 들어서 해본다면

 

위와 같은 형태와 비슷하게 만들어 질 것이다.

 

한 눈에 본다면 이런 느낌

 

하지만 예외 경우가 있는데 원 쿠션이 가기도 전에 만나버리는 경우다.

이런 경우만 제외하고 각 벽을 기준으로 대칭한 후에 직선 거리를 구하면 된다.

 

직선 거리 구하기 (x1, y1) (x2, y2)일 때

직선 거리^2 = (x2-x1)^2 + (y2-y1)^2

 

풀이

더보기
class Solution {
    public int[] solution(int m, int n, int startX, int startY, int[][] balls) {
        int[] answer = new int[balls.length];
        
        for (int i=0; i<balls.length; i++) {
            int[] ball = balls[i];
            // 기존 좌표
            int exampleTargetX = ball[0];
            int exampleTargetY = ball[1];
            // 대칭 좌표
            int symmetryTargetX;
            int symmetryTargetY;
            
            // 거리 제곱 계산
            int distance = Integer.MAX_VALUE;
            // 상 대칭 시 원쿠션이 되지 않는 경우
            if (!((startX == exampleTargetX) && (startY <= exampleTargetY))) {
                // 상 대칭 좌표
                symmetryTargetX = exampleTargetX;
                symmetryTargetY = n + (n - exampleTargetY);
                distance = Math.min(distance, (int) Math.pow(startX-symmetryTargetX, 2) + (int) Math.pow(startY-symmetryTargetY, 2));
            }
            
            // 하 대칭
            // 하 대칭 시 원쿠션이 되지 않는 경우
            if (!((startX == exampleTargetX) && (startY >= exampleTargetY))) {
                // 하 대칭 좌표
                symmetryTargetX = exampleTargetX;
                symmetryTargetY = -exampleTargetY;
                distance = Math.min(distance, (int) Math.pow(startX-symmetryTargetX, 2) + (int) Math.pow(startY-symmetryTargetY, 2));
            }
            
            // 좌 대칭
            // 좌 대칭 시 원쿠션이 되지 않는 경우
            if (!((startY == exampleTargetY) && (startX >= exampleTargetX))) {
                // 좌 대칭 좌표
                symmetryTargetX = -exampleTargetX;
                symmetryTargetY = exampleTargetY;
                distance = Math.min(distance, (int) Math.pow(startX-symmetryTargetX, 2) + (int) Math.pow(startY-symmetryTargetY, 2));
            }
            
            // 우 대칭
            // 우 대칭 시 원쿠션이 되지 않는 경우
            if (!((startY == exampleTargetY) && (startX <= exampleTargetX))) {
                // 우 대칭 좌표
                symmetryTargetX = m + (m-exampleTargetX);
                symmetryTargetY = exampleTargetY;
                distance = Math.min(distance, (int) Math.pow(startX-symmetryTargetX, 2) + (int) Math.pow(startY-symmetryTargetY, 2));
            }
            
            answer[i] = distance;
        }
        
        
        return answer;
    }
}
Comments