프로그래머스/Lv.1

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

MINU.SHINNNN 2023. 10. 23. 00:01

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

 

프로그래머스

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

programmers.co.kr

풀이

키패드를 누르는 순서 numbers 및 왼손잡이/오른손잡이를 나타내는 변수 hand가 주어질 때, 번호를 누르는 엄지손가락(L or R)에 따라 answer에 순차적으로 이어붙여 출력하는 문제입니다.

 

번호에 따라 현재 위치를 알아내는 방법만 생각하면 해결할 수 있는 문제입니다. 번호가 주어졌을 때, 현재 (row, col)은 (현재수-1)/3, (현재수-1)%3 으로 알아낼 수 있습니다. 또는 map, unordered_map<int, pair<int, int>> 자료구조를 사용해서 미리 해싱할 수도 있습니다.

해당 문제에서는 전자의 방법을 사용해 구현하였습니다.

 

초기위치 *, #은 키패드 위치상 10과 12입니다. numbers를 순회하며 왼손, 오른손을 추가하며 2, 5, 8, 0인 경우에만 거리를 계산하여 기준에 맞게 answer에 추가해줍니다. 이떄, curr_l, curr_r 이 0인 경우 위치가 (3, 1)임에 유의합니다. 거리가 같은경우 hand에 따라 answer를 추가하면 정답을 리턴할 수 있습니다.

 

리뷰

해싱을 사용해 풀 경우 0일때 예외처리를 안해도 되기 때문에 더 짧은 코드가 될 것입니다.

#include <string>
#include <vector>
#include <iostream>
#include <cmath>

using namespace std;
// 1- 0,0 2- 0,1 3- 0,2
// 4- 1,0 5 - 1,1 6- 1,2 
// 위치: (현재수-1)/3, (현재수-1)%3
// 0인 경우 3,1
// 키패드 거리가 같다면 오른잡이는 오른손, 왼손잡이는 왼손
string solution(vector<int> numbers, string hand) {
    string answer = "";

    // 왼손, 오른손 현재 위치 기록용 변수
    int curr_l = 10, curr_r = 12;
    // 다음 목표 까지 거리 계산용 변수
    int nx, ny;
    for (int i=0; i<numbers.size(); i++) {
        int num = numbers[i];
        if (num == 1 || num == 4 || num == 7) {
            answer += "L";
            curr_l = num;
        }
        else if (num == 3 || num == 6 || num == 9) {
            answer += "R";
            curr_r = num;
        }
        else {
            if (num == 0) {
                ny = 3;
                nx = 1;
            }
            else {
                ny = (num-1)/3;
                nx = (num-1)%3; 
            }
            // 거리 계산
            int dist_l, dist_r;
            if (curr_l == 0) 
                dist_l = abs(ny-3) + abs(nx - 1);
            else 
                dist_l = abs(ny-(curr_l-1)/3) + abs(nx - (curr_l-1)%3);
            
            if (curr_r == 0)
                dist_r = abs(ny-3) + abs(nx - 1);
            else
                dist_r = abs(ny-(curr_r-1)/3) + abs(nx - (curr_r-1)%3);
            
            // 거리 및 hand에 따라 판단
            if (dist_l == dist_r) {
                if (hand == "left") {
                    answer += "L";
                    curr_l = num; 
                }
                else {
                    answer += "R";
                    curr_r = num;
                }
            }
            else if (dist_l < dist_r) {
                answer += "L";
                curr_l = num;
            }
            else {
                answer += "R";
                curr_r = num;
            }
        }
    }
    return answer;
}