알고리즘

프로그래머스 42860 - 조이스틱

ljw4104 2021. 9. 9. 17:36

문제 설명 - 그리디 알고리즘

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA

조이스틱을 각 방향으로 움직이면 아래와 같습니다.

▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동

예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.

- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

입출력 예시

name return
"JEROEN" 56
"JAN" 23

개인적으로 굉장히 어려웠던 문제 중에 하나...

문제 풀이를 보고도 이해하는데 엄청 오래 걸렸다.

특히 좌 -> 우로 움직이거나 우 -> 좌 로 움직이는 걸 판별하기 위해서 이걸 어떻게 생각해야되나 고민했다.

뒤로 움직일 때의 조건은 A가 나왔을 때를 기준으로 계산하면 된다.

  1. 좌 -> 우로 움직이는 것 : 문자열의 길이
  2. 우 -> 좌로 움직이는 것 : 다시 처음으로 돌아와서 백트래킹하는 거리

다음 두 가지를 비교하여 더 작은 값을 대입해주면 될 거 같다.

 

Python

def solution(name):
    answer = 0
    a = ord('A')
    z = ord('Z')
    min_move = len(name)
    next_idx = 0
    for idx, value in enumerate(name):
        # 위, 아래 조작값의 최솟값 구하기
        answer += min(ord(value) - a, z - ord(value) + 1)
        
        next_idx += 1
        #연속되는 A의 구간을 확인 / WHILE문이 끝나면 A의 마지막 인덱스가 저장될꺼임
        while next_idx < len(name) and name[next_idx] == 'A':
            next_idx += 1
        
        #좌 → 우 로 이동하는 것과 다시 처음으로 돌아가는 우 → 좌의 방법 중 작은 값을 고름
        min_move = min(min_move, idx + idx + len(name) - next_idx)
    answer += min_move
    return answer

 

C++

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

int solution(string name) {
    int answer = 0;
    int a = 65;
    int z = 90;
    int next_idx = 0;
    int min_move = name.size();
    
    for(int i = 0; i < name.size(); i++){
        answer += min(name[i] - a, z - name[i] + 1);
        next_idx++;
        
        while(next_idx < name.size() && name[next_idx] == 'A'){
            next_idx++;
        }
        min_move = min<int>(min_move, i + i + name.size() - next_idx);
    }
    answer += min_move;
    return answer;
}