Game Develop

[Algorithm] Programmers :: 당구 연습 본문

Algorithm/Programmers

[Algorithm] Programmers :: 당구 연습

MaxLevel 2023. 6. 17. 04:15

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

 

프로그래머스

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

programmers.co.kr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
vector<int> solution(int m, int n, int startX, int startY, vector<vector<int>> balls) 
{
    vector<int> answer;
 
    for (int i = 0; i < balls.size(); ++i)
    {
        int destY = balls[i][1];
        int destX = balls[i][0];
        int minDistance = 10000000;
 
        int newY = 0;
        int newX = 0;
 
        if (startY != destY && startX != destX) // y,x 둘 다 다르면.
        {
            // 상
            newY = 2 * n - startY;
            newX = startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            // 하
            newY = startY * -1;
            newX = startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            // 좌
            newY = startY;
            newX = startX * -1;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            // 우
            newY = startY;
            newX = 2 * m - startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
        }
        else if (startY == destY)
        {
            // 상
            newY = 2 * n - startY;
            newX = startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            // 하
            newY = startY * -1;
            newX = startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            if (startX < destX)
            {
                // 좌
                newY = startY;
                newX = startX * -1;
                minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
            }
            else
            {
                // 우
                newY = startY;
                newX = 2 * m - startX;
                minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
            }
        }
        else if (startX == destX)
        {
            // 좌
            newY = startY;
            newX = startX * -1;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            // 우
            newY = startY;
            newX = 2 * m - startX;
            minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
 
            if (startY > destY)
            {
                // 상
                newY = 2 * n - startY;
                newX = startX;
                minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
            }
            else
            {
                // 하
                newY = startY * -1;
                newX = startX;
                minDistance = min(minDistance, (int)pow(destY - newY, 2+ (int)pow(destX - newX, 2));
            }
        }
 
        answer.push_back(minDistance);
    }
 
    return answer;
}
cs

 

수학지식을 요하는 문제인데, 관련된 문제를 다룬적이 없었어서 다시 공부한다음 풀었다.

코드가 되게 긴데, 사실 저렇게 길 필요는 없긴 하다만 굳이 다듬지는 않았다. 이 문제에서 확실히 인지해야할 것은 수학원리니까..

 

기본적으로 각 벽에 대하여 쳤을 때에 대하여 거리를 구한다음 최솟값을 구하면 된다.

그렇다면 각 벽에 쳤을 때의 거리가 몇인가?가 관건이다.

이건 따로 설명할 필요없이 구글에다가 '입사각과 반사각'에 대하여 검색해서 이해하면 알 수 있다.

입사각과 반사각이 동일하다는 전제가 있기 때문에, 점을 대칭시켜서 시작점과 도착점을 일직선으로 만들어버린다는 원리이다.

그리고 문제에서 구하라고 하는것은, 직선거리가 아니라 직선거리의 제곱이기때문에 루트연산을 할 필요 없다는것을 인지하자.