매일 조금씩

프로그래머스 level2 : 당구 연습 - Java 본문

알고리즘

프로그래머스 level2 : 당구 연습 - Java

mezo 2023. 6. 9. 20:42
728x90
반응형

 

 

이문제는 구현 문제이다.

원쿠션을 한다는 것을 통해 벽을 기준으로 점을 대칭시킨다는 생각을 가장 먼저 해야하고,

시작공과 목표 공이 x축이나 y축에 수평으로 놓여있을때 4개의 벽 한 벽에선 시작공이 벽보다 목표공을 맞추게 되므로 이를 예외 시켜야한다. 

 

 

import java.util.*;

class Solution {
    
    static class Point{
        int x,y;
        public Point(int x, int y){
            this.x = x;
            this.y = y;
        }
    }
    
    public int[] solution(int m, int n, int startX, int startY, int[][] balls) {
        int[] answer = new int[balls.length];
        
        Point border = new Point(m,n);
        Point start = new Point(startX,startY);
        
        for(int i = 0; i < balls.length ; i++){
            int[] ball = balls[i];
            
            // 목표 공들을 벽 4개에 대칭시킨 점을 담음
            List<Point> transBall = sysmmetricTransposition(border, start, new Point(ball[0], ball[1]));
            
            // 제일 짧은 거리의 점을 구함
            int minDistance  = Integer.MAX_VALUE;
            for(Point point : transBall){
                int dis = calculationDistance(start, point);
                
                minDistance = Math.min(minDistance, dis);
            }
            
            answer[i] = minDistance;
        }
        
        return answer;
    }
    
    // 시작공과 목표공을 잇는 선이 벽과 수직이 되는 경우의 벽은 제외 - 벽보다 목표하는 공을 먼저 침
    private List<Point> sysmmetricTransposition(Point border, Point start, Point ball){
        List<Point> syms = new ArrayList<>();
        
        // 위쪽 벽에 대칭
        if(!(start.x == ball.x && start.y < ball.y)) syms.add(new Point(ball.x, 2 * border.y - ball.y ));
        // 오른쪽 벽에 대칭
        if(!(start.y == ball.y && start.x < ball.x)) syms.add(new Point(2 * border.x - ball.x, ball.y));
        // 아래쪽 벽에 대칭
        if(!(start.x == ball.x && start.y > ball.y)) syms.add(new Point(ball.x, ball.y * -1));
        // 왼쪽 벽에 대칭
        if(!(start.y == ball.y && start.x > ball.x)) syms.add(new Point(ball.x * -1 , ball.y));
        
        return syms;
    }
    
    private int calculationDistance(Point start, Point ball){
        int bigX = Math.max(start.x, ball.x);
        int smallX = Math.min(start.x, ball.x);
        int bigY = Math.max(start.y, ball.y);
        int smallY = Math.min(start.y, ball.y);
        
        return (int)Math.pow(bigX - smallX, 2) + (int)Math.pow(bigY - smallY, 2);
    }
}
728x90
반응형