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

최민길(Gale)·2023년 7월 6일
1

알고리즘

목록 보기
89/172

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/169198

이 문제는 선대칭을 이용하여 문제를 풀 수 있습니다. 이 문제의 핵심은 쿠션에 맞고 나온 당구공의 위치를 파악하는 것입니다. 당구공의 위치는 선대칭을 이용하여 풀 수 있습니다. 당구장의 각 방향, 즉 상하좌우 방향으로 당구공이 이동할 경우 이동할 방향의 당구장 벽에 당구공을 대칭시킨 좌표와 시작 지점 사이의 거리가 곧 문제에서 요구하는 거리가 됩니다. 그 이유는 입사각과 반사각이 같기 때문에 각이 형성된 직선, 즉 당구장 벽면을 기준으로 하나의 공을 대칭시키면 두 직선 사이의 마주보는 사이각이 같다는 법칙으로 인해 이 공 역시 거리가 같게 되며, 직선 사이의 거리 공식을 이용하여 더 쉽게 구할 수 있기 때문입니다.

하지만 여기서 주의할 점이 있습니다. 바로 시작 공보다 타겟 공이 더 앞서 있는 경우입니다. 이 경우는 해당 방향으로 선대칭한 값으로 거리가 정해지는 것이 아니라 반대쪽 쿠션으로 넘어가야 시작공이 벽에 맞을 수 있기 때문에 시작 공보다 타겟 공이 더 앞서 있는 경우는 경로 계산에 포함하면 안됩니다.

다음은 코드입니다.

import java.util.*;

class Solution {
    static int N,M,sy,sx;
    
    public List<Integer> solution(int m, int n, int startX, int startY, int[][] balls) {
        List<Integer> answer = new ArrayList<>();
        N = n; M = m; sy = startY; sx = startX;
        for(int[] ball : balls){
            Ball curr = new Ball(ball[1],ball[0]);
            answer.add(curr.getMinDistance());
        }
        
        return answer;
    }
    
    static class Ball{
        int y;
        int x;
        
        Ball(int y, int x){
            this.y = y;
            this.x = x;
        }
        
        int getMinDistance(){
            int res = Integer.MAX_VALUE;
            List<Ball> balls = new ArrayList<>();
            // 위 방향 이동
            if(!(x==sx && y<sy)) balls.add(new Ball(y*-1,x));
            
            // 아래 방향 이동
            if(!(x==sx && y>sy)) balls.add(new Ball(2*N-y,x));
            
            // 왼쪽 방향 이동
            if(!(y==sy && x<sx)) balls.add(new Ball(y,x*-1));
            
            // 오른쪽 방향 이동
            if(!(y==sy && x>sx)) balls.add(new Ball(y,2*M-x));
            
            for(Ball ball : balls){
                int diffY = Math.abs(sy-ball.y);
                int diffX = Math.abs(sx-ball.x);
                int d = (int)Math.pow(diffY,2) + (int)Math.pow(diffX,2);
                res = Math.min(res,d);
            }
            
            return res;
        }
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글