본문 바로가기
코딩테스트 준비/프로그래머스

[프로그래머스][C++] 키패드 누르기

by 스테디코디스트 2023. 10. 16.
반응형

<문제 소개>


<소스 코드>

#include <string>
#include <vector>

using namespace std;

string solution(vector<int> numbers, string hand) 
{
    string answer = "";
    
    // 각 손의 초기 위치
    int curLeft = 10; // *
    int curRight = 12; // #
    
    for(int i = 0; i < numbers.size(); i++)
    {
        // 0은 위치상 11로 간주
        int curNum = numbers[i] == 0 ? 11 : numbers[i];
        
        if(curNum % 3 == 1)
        {
            // 1, 4, 7
            answer += "L";
            curLeft = curNum;
        }
        else if(curNum % 3 == 0)
        {
            // 3, 6, 9
            answer += "R";
            curRight = curNum;
        }
        else
        {
            // 2, 5, 8, 0
            
            // [x,y]로 표현
            int curX = curNum % 3 - 1;
            int curY = curNum / 3;
            
            int leftX = curLeft % 3 - 1;
            int leftY = curLeft / 3;
            
            int rightX = (curRight-1) % 3;
            int rightY = (curRight-1) / 3;
            
            // gap 구하기
            int LeftGap = abs(leftX - curX) + abs(leftY - curY);
            int RightGap = abs(rightX - curX) + abs(rightY - curY);
            
            if(LeftGap > RightGap)
            {
                // 왼쪽 갭이 큰 경우 -> 오른쪽 손으로 터치
                answer += "R";
                curRight = curNum;
            }
            else if(LeftGap < RightGap)
            {
                // 오른쪽 갭이 큰 경우 -> 왼쪽 손으로 터치
                answer += "L";
                curLeft = curNum;
            }
            else
            {
                // 갭이 같은 경우 -> 어떤 손잡이인지 판단하여 터치 
                if(hand == "left")
                {
                    answer += "L";
                    curLeft = curNum;
                }
            
                if(hand == "right")
                {
                    answer += "R";
                    curRight = curNum;
                }             
            }
        }
    }
    
    return answer;
}

<풀이과정>

1. 각 손의 기본 위치를 curLeft, curRight로 각각 10, 12로 선언

2. numbers를 반복

3. 현재 눌러야할 숫자를 curNum으로 저장하는데 0은 위치상 11로 간주하여 저장

4. if문을 이용해 조건을 나누어 각 키패드를 누를 손을 결정한다.

5. [1, 4, 7] 중 하나를 누르는 경우

5-1. 이 숫자들은 항상 왼손으로 눌러야하므로 answer에 "L"을 저장

5-2. 왼손의 위치가 바뀌었으므로 처음에 선언한 왼손의 위치인 curLeft를 현재 숫자로 바꿔줌

6. [3, 6, 9] 중 하나를 누르는 경우

6-1. 이 숫자들은 항상 오른손으로 눌러야하므로 answer에 "R"을 저장

6-2. 오른손의 위치가 바뀌었으므로 마찬가지로 오른손의 위치인 curRight를 현재 숫자로 바꿔줌

7. [2, 5, 8, 0] 중 하나를 누르는 경우

7-1. 이 경우에는 먼저 눌러야할 키패드와 거리가 가까운 손이 누르고, 거리가 같다면 자신의 손잡이에 따라서 키패드를 누르게 된다.

7-2. 키패드는 3x4 배열의 형태로 표현할 수 있는데, 현재 눌러야할 키패드의 위치와 각 손의 위치를 배열로 나타내고, x,y값의 차를 구해 거리를 나타낼 수 있다.

7-3. curNum의 x,y 좌표는 curX, curY로 선언하고 해당 숫자들은 가운데 있는 수들만 해당하므로 각 수에 맞게 연산을 통해 좌표값을 구한다.

7-4. curLeft의 좌표도 항상 왼쪽 수들이거나 가운데 있는 수들 중에 하나이므로 curNum과 같은 방식으로 연산을 해준다.

7-5. curRight의 좌표는 오른쪽 키패드가 눌리는데 이는 3으로 나누어 떨어지는 수들을 포함하기 때문에 조금 다른 방식의 연산을 통해 좌표값을 구해준다.

7-6. 이제 모든 좌표가 구해졌으므로 curX와 각 X좌표의 차이, curY와 각 Y좌표의 차이를 구한뒤 더해서 왼쪽과 오른쪽 손이 현재 눌러야할 키패드와 얼마나 떨어져있는지를 나타내는 갭을 구해준다.

7-7. 구한 갭을 이용해 왼쪽 갭이 오른쪽 갭보다 크다면 오른쪽 손으로 눌러주고, 왼쪽 갭이 더 작다면 왼쪽 손으로 눌러준다.

7-8. 만약 갭이 같다면 hand가 left이면 왼손으로 right이면 오른손으로 각각 눌러주는 작업을 해준다. 


<코멘트>

 

 

가운데 숫자를 누르는 방식이 조금 까다로웠다.


<제출결과>