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

2022. 4. 25. 22:41카테고리 없음

문제

https://programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

이 문제의 관건은 경우의 수를 잘 나누고, 이에 따라 수학적으로 구현을 잘 적용하는 것이 중요했다.

가장 어려울 수 있는 부분은 버튼 간 거리를 구하는 점이다.

 

하지만 각각의 버튼을 간단히 '행렬'을 적용해 생각해보면 쉬워지는 문제다.

1~9을 각각 [0,0], [0,1]...[2,2]식으로 처리하여 거리를 계산하면 된다.

 

그리고 제일 하단의 #, 0, *를 어떻게 처리할지 처음에 당황스러울 수 있다.

왜냐하면 위의 1~9와 다른 규칙을 지녔기 때문이다.

하지만 *, 0, #에  1~9와 같은 규칙을 동일하게 적용하면 된다.

즉, *을 10으로, 0을 11로, #을 12로 설정해서 규칙을 적용하면 된다.

 

또한 행렬에서 각각 row, col을 구할 때 주의해야 하는 점이 있다.

그냥 1~9에서 몫과 나머지를 구하는 연산을 하면 어렵다.

그러나 1씩 감소한 0~8에서 구하면 쉬워진다.

이런 식으로 문제의 요건들을 간단하게 만들어서 구현하면 된다.

#include <string>
#include <vector>
#include <iostream>
using namespace std;
int left_num = 10;
int right_num = 12;
int left_dist = 0;
int right_dist = 0;
int zero_pos = 11;
int distance(int a, int b) {
    if(a == b) return 0;
    int big = a > b ? a - 1 : b - 1;
    int small = a < b ? a - 1 : b - 1;
    
    int big_row = big / 3;
    int big_col = big % 3 == 0 ? 2 : big % 3;
    int small_row = small / 3;
    int small_col = small % 3 == 0 ? 2 : small % 3;
    return (big_row - small_row) + abs(big_col - small_col);
}
string solution(vector<int> numbers, string hand) {
    string answer = "";
    for(auto num : numbers){
        switch(num){
            case 1: case 4: case 7:
                answer += "L";
                left_num = num;
                break;
            case 3: case 6: case 9:
                answer += "R";
                right_num = num;
                break;
            case 2: case 5: case 8:
                left_dist = distance(num, left_num);
                right_dist = distance(num, right_num);
                if(left_dist == right_dist) {
                    if(hand == "right"){
                        answer += "R";
                        right_num = num;
                    }
                    else {
                        answer += "L";
                        left_num = num;
                    }
                }
                else if(left_dist < right_dist) {
                    answer += "L";
                    left_num = num;
                }
                else {
                    answer += "R";
                    right_num = num;
                }
                break;
            case 0:
                left_dist = distance(zero_pos, left_num);
                right_dist = distance(zero_pos, right_num);
                if(left_dist == right_dist) {
                    if(hand == "right"){
                        answer += "R";
                        right_num = zero_pos;
                    }
                    else {
                        answer += "L";
                        left_num = zero_pos;
                    }
                }
                else if(left_dist < right_dist) {
                    answer += "L";
                    left_num = zero_pos;
                }
                else {
                    answer += "R";
                    right_num = zero_pos;
                }
                break;
        }
    }
    return answer;
}