프로그래머스 lv 2. 42860 조이스틱 c++

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

 

#include <bits/stdc++.h>

using namespace std;

int solution(string name){
    int answer=0;
    int n = name.length();
    int turn = n-1;
    for(int i=0; i<n; i++){
        if(name[i]-'A'<14) answer+=name[i]-'A';
        else answer+='Z'- name[i]+1;
        
        int ind=i+1;
        while(ind < n && name[ind] == 'A') ind++;
        //이때에 a= i, b= n-ind;
        // 첫번재 자리부터, a 이동, 되돌아오기 a 이동, 뒤로 꺽어서 b 이동
        // 첫번째 자리부터, 뒤로 꺽어서 b 이동, 되돌아오기 b 이동, a 이동 순으로 생각했을때
        // a + a + b 와 b + b +a 를 비교해서 더 작은 값을 갖는것이 가장 작은 이동횟수가 된다. 
        turn = min(turn , i+(n-ind) + min(i, (n-ind)));// 이해하기 쉽게 (n-ind)에 괄호를 침
        //turn = min(turn, i+ n-ind + min(i, n-ind)); 로 작성해도 무방함.
    }
    answer+= turn; 
    return answer;
}

 

turn 이라는 변수에 좌우로 이동하는 값의 최소를 담아내는 형태로 작성해서 마지막에 더해주고, 

위아래로 움직이면서 알파벳을 변경시키는 변수는 개별 변경 과정에서 더해주는 형태로 작성된 코드 

 

다른 사람의 풀이를 볼때, 위로 올려서 변형시킬지, 혹은 아래로 내려서 변형시킬지에 대한 처리를 값들을 미리 계산해서 나타내는 풀이가 있어서 첨부해본다. 

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int LUT[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1 };

int solution(string name) {
    int answer = 0;
    for (auto ch : name)
        answer += LUT[ch - 'A'];
    int len = name.length();
    int left_right = len - 1;
    for (int i = 0; i < len; ++i) {
        int next_i = i + 1;
        while (next_i < len && name[next_i] == 'A')
            next_i++;
        left_right = min(left_right, i + len - next_i + min(i, len - next_i));
    }
    answer += left_right;
    return answer;
}

결국 이 풀이도 좌우로 이동하는건 마지막에 더하고, 위아래로 이동시키는 값은 최초에 그냥 계산해서 바로 answer에 추가해버리는 식이다. 

모든 알파벳들에 대해서 이동할 것이 있다면, 미리 계산해놓은 상황에 따라 위아래로 어떤걸 선택할지를 결정하는 풀이가 재미있는 부분인것 같다. 

 

이 문제 lv2 라고 생각하기에는 어려운 문제라 생각된다. 

 

  Comments,     Trackbacks