coding_test/programmers

lv1 / 키패드 누르기 / 카카오 기출 / C++

CodeJin 2022. 7. 13. 14:24

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

 

프로그래머스

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

programmers.co.kr


거리를 어떻게 따져야 할지가 정말 고민이어서, "그래프를 작성하고 최단거리 알고리즘을 돌려야 하나" 라고 생각할 정도로 생각을 많이 했었는데, 생각해보니까 *, 0, #을 각각 10, 11, 12로 생각해보니까, 거리를 구하는 방법이 떠올랐다. 

 

1 2 3
4 5 6
7 8 9
10(*) 11(0) 12(#)

 

키패드가 다음과 같이 구성되어있으므로, 두 번호간의 거리는, (두 번호의 y축방향 차이) + (두 번호의 x축방향 차이)로 생각할 수 있다. 이때의 y축은 3으로 나눈 몫이 될 것이고, x축은 3으로 나눈 나머지가 될 것이다. 그러면 현재의 손가락 위치와, 누르고자 하는 버튼의 차이를 구하고, 각각 몫값과 나머지값을 합하면 될 것 같았다.

 

1과 11을 생각해보자. 두 수의 차는 10이고, 3으로 나눈 몫은 3, 나머지는 1이니까, 이 두 수의 거리는 4이고, 실제로 세보면 4이다. 여러가지 숫자를 대입해봐도 맞는 것을 알 수 있다.

 

#include <bits/stdc++.h>
using namespace std;

int rfing, lfing;

int dist(int finger, int target) {
    int temp = abs(finger-target);
    return (temp / 3) + (temp % 3);
}

void make_ans(string& answer, int is_left, int target) {
    // left == 1이면 왼손, 0이면 오른손
    if (is_left) {
        answer += "L";
        lfing = target;
    } else {
        answer += "R";
        rfing = target;
    }
}

string solution(vector<int> numbers, string hand) {
    string answer = "";
    rfing = 12; // "#"
    lfing = 10; // "*"
    for (int num : numbers) {
        if (num == 0) num = 11;
        
        if (num % 3 == 0) make_ans(answer, 0, num);
        else if (num % 3 == 1) make_ans(answer, 1, num);
        else if (num % 3 == 2 ) {
            int right_dist = dist(rfing, num);
            int left_dist = dist(lfing, num);

            if (right_dist > left_dist) make_ans(answer, 1, num);
            else if (right_dist < left_dist) make_ans(answer, 0, num);
            else {
                if (hand == "right") make_ans(answer, 0, num);
                else make_ans(answer, 1, num);
            }
        }
    }
    return answer;
}