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

최민길(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개의 댓글

관련 채용 정보