[프로그래머스] 키패드 누르기
2022. 4. 25. 22:41ㆍ카테고리 없음
문제
https://programmers.co.kr/learn/courses/30/lessons/67256
이 문제의 관건은 경우의 수를 잘 나누고, 이에 따라 수학적으로 구현을 잘 적용하는 것이 중요했다.
가장 어려울 수 있는 부분은 버튼 간 거리를 구하는 점이다.
하지만 각각의 버튼을 간단히 '행렬'을 적용해 생각해보면 쉬워지는 문제다.
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;
}