본문 바로가기
PS

프로그래머스 Level 2 조이스틱 C++

by mtoc 2020. 4. 5.

문제 설명

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

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

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

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

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

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

제한 사항
  • name은 알파벳 대문자로만 이루어져 있습니다.
  • name의 길이는 1 이상 20 이하입니다.
입출력 예
namereturn
JEROEN56
JAN23




코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string>
using namespace std;
 
int solution(string name) {
    int answer = 0;
    string init_name = "";
    for(int i=0; i<name.size(); i++) init_name += "A";
 
    int cur = 0;
    while(name != init_name) {
        int left = 0, right = 0, minStep = name.size(), minIdx = 0;
        for(int i=0; i<name.size(); i++) {
            if(name[i] == init_name[i]) continue;
 
            if(cur > i) {
                left = cur - i;
                right = name.size() - cur + i;
            } else {
                left = cur + name.size() - i;
                right = i - cur;
            }
 
            if(left < minStep || right < minStep) {
                minStep = min(left, right);
                minIdx = i;
            }
        }
 
        cur = minIdx;
        answer += minStep;
        answer += min(name[cur] - 'A''Z' - name[cur] + 1);
        init_name[cur] = name[cur];
    }
 
    return answer;
}
cs

효율 생각하지 않고 짠 코드이긴 하다.

정말 단순하게, 맨 처음의 답('AAA...')에서 시작해서 정답과 같아질 때까지 while문을 반복한다.

while문의 코드는 다음과 같이 동작한다.


1. 0부터 name.size() - 1까지 돌면서 해당 인덱스의 문자가 정답과 같지 않으면 현재 위치에서 왼쪽으로 가는 경우 / 오른쪽으로 가는 경우의 이동 횟수를 계산한다. 만약 최소 이동 횟수보다 작으면 최소 이동 횟수에 대입.

2 . cur(현재 위치)에 위의 for문에서 최소 이동 횟수를 구했던 인덱스를 저장한 minIdx를 대입.

3. 현재 위치로부터 위로 눌러야 이득인지 아래로 눌러야 이득인지 계산해서 최솟값 더함.

4. 현재 위치의 문자를 정답 문자로 바꿈.


알고리즘 자체는 최악으로 동작하지만 정답은 나온다.

나는 직관적으로 이렇게 생각했고 나보다 더 깔끔하게 푼 분들의 코드가 검색해보면 많이 나온다...

평소에 공부 좀 해야겠다 ㅠ


댓글