Algorithm/백준과 프로그래머스

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

young_3060 2024. 1. 19. 13:00
728x90

 

 

 

 

 

숫자가 {2,5,8,0} 일때를 잘 다루는것이 관건!

처음에는, 단순히 현재 위치와 target값을 빼주고, 그 값이 3이면 1으로 바꿔주는 계산방식을 생각했었다.

하지만 만약 target=6이고 현재 위치가(왼손이든 오른손이든) 7이라면, 실제거리는 3이지만 이 로직은 1이라고 말할 것이다.

따라서, 전체 키패드를 격자로 생각하고, 각각의 좌표를 구해준 뒤 좌표 거리 계산을 해주어야 한다!

 

자세한 내용은 주석을 참고바란다.

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

/*
시작 : 왼손 엄지 - *(10), 오른손 엄지 - #(12)
상하좌우 한칸씩만 이동가능

1,4,7 => 왼손, 3,6,9 => 오른손
2,5,8,0(11) => 둘 중 가까운 손 (거리 같으면 왼손잡이, 오른손잡이 참고)

[calculate 함수]
격자를 그려서, 좌표 계산 후 return
X축 = {0,1,2} , Y축 = {0,1,2,3} 이므로
X축은 (X-1)%3, Y축은 (Y-1)/3 으로 격자 형태의 좌표값을 얻는다.
얻은 좌표값으로 계산 후 return
*/

int calculate(int curr, int target) {
    if(curr == 0) curr = 11;
    if(target == 0) target = 11;

    int currX = (curr-1) % 3;
    int currY = (curr-1) / 3;
    int tarX = (target-1) % 3;
    int tarY = (target-1) / 3;

    return abs(currX-tarX) + abs(currY-tarY);
}

string solution(vector<int> numbers, string hand) {
    string answer = "";
    int left = 10, right = 12;
    for(auto number : numbers) {
        if(number==0) number = 11;
        if(number % 3 == 1) {
            left = number;
            answer += 'L';
        }
        else if(number % 3 == 0) {
            right = number;
            answer += 'R';
        }
        else {
            int leftN = calculate(left, number);
            int rightN = calculate(right, number);

            if(leftN < rightN) {
                left = number;
                answer += 'L';
            }
            else if(leftN > rightN) {
                right = number;
                answer += 'R';
            }
            else {
                if(hand=="left") {
                    left = number;
                    answer += 'L';
                }
                else {
                    right = number;
                    answer += 'R';
                }
            }
        }
    }
    return answer;
}
728x90