학습/프로그래머스

[프로그래머스] 당구 연습(java)

태기 2023. 7. 6. 16:34

문제

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


나의 풀이

import java.util.ArrayList;
import java.util.List;

class Solution {
    public int[] solution(int m, int n, int startX, int startY, int[][] balls) {
        int[] answer = new int[balls.length];

        Point start = new Point(startX, startY);

        for (int i = 0; i < balls.length; i++) {
            int[] ball = balls[i];

            List<Point> siteList = new ArrayList<>();
            if(!(start.x == ball[0] && start.y < ball[1])) siteList.add(new Point(ball[0], n + (n - ball[1])));
            if(!(start.x == ball[0] && start.y > ball[1])) siteList.add(new Point(ball[0], -ball[1]));
            if(!(start.x < ball[0] && start.y == ball[1])) siteList.add(new Point(m + (m - ball[0]), ball[1]));
            if(!(start.x > ball[0] && start.y == ball[1])) siteList.add(new Point(-ball[0], ball[1]));

            int minDistance = (int) Math.pow(m, 2) + (int) Math.pow(n, 2);

            for (Point point : siteList) {
                int x = start.x > point.x ? start.x - point.x : point.x - start.x;
                int y = start.y > point.y ? start.y - point.y : point.y - start.y;

                int dis = (int) Math.pow(x, 2) + (int) Math.pow(y, 2);
                minDistance = minDistance > dis ? dis : minDistance;
            }
            answer[i] = minDistance;
        }

        return answer;
    }
}

class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

입사각, 반사각이 같으니 목적구의 대칭이동을 생각해서 풀었다. 각 방향으로 거리를 구한 뒤 최솟값을 뽑아내는 방법으로 구현했다.

 

제약조건은 목적구가 x축 같은 라인이거나 y축 같은 라인일 때 쿠션에 맞기 전에 공을 먼저 맞게 되므로 제외시키는 것을 추가했다. 

 

이해가 안될 수 있으니 예를들어, 시작구는 (4, 5), 목적구가 (4, 8) 에 있을 때 위쪽 쿠션으로 치게 되면 공이 먼저 맞기 때문에 그 부분을 제외한다. (그림 보면 이해 될텐데, 그리기 귀찮...)