[프로그래머스] 조이스틱
📌 문제 설명
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA
조이스틱을 각 방향으로 움직이면 아래와 같습니다.
▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.
- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.
📌 제한 사항
- name은 알파벳 대문자로만 이루어져 있습니다.
- name의 길이는 1 이상 20 이하입니다.
🔗 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/42860
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
👩💻 코드
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int solution(string name) {
int answer = 0;
int n = name.size();
int minMoves = n - 1;
for(int i=0; i<n; i++){
int next = i + 1;
while (next < n && name[next] == 'A') {
next++;
}
int left = i + i + n - next;
int right = i + (n - next) * 2;
minMoves = min(minMoves, min(left, right));
int dis = name[i] - 'A';
answer += min(dis, 26 - dis);
}
return answer + minMoves;
}
📝 풀이
조이스틱을 상하 조작으로 알파벳을 변경하는 것과 좌우 조작으로 커서 위치를 변경하는 횟수를 나누어 구합니다.
커서 위치를 변경하는 횟수를 구하기 위해서 먼저 연속된 'A'의 위치를 구해야 합니다.
연속된 마지막 위치의 'A'의 찾기 위해 while 반복문을 사용합니다.
left 값은 현재 위치에서 왼쪽 끝으로 돌아간 후 (i + i) 연속된 'A'의 뒤의 next 위치까지 (n - next) 이동거리입니다.
right 값은 커서를 오른쪽으로 이동 (i) 후 마지막으로 연속된 'A' 구간을 지나 next까지 한 번에 왼쪽으로 ((n - next)* 2) 돌아가는 이동거리입니다.
둘 중 더 적은 횟수로 이동할 수 있는 값으로 minMoves를 갱신합니다.
알파벳을 변경하는 것은 'A'부터 이동 거리와 'Z'부터 역방향으로 이동 거리를 비교하여 적은 값을 answer에 누적합니다.
최종적으로 상하 조작 횟수 answer과 좌우 조작 횟수 minMoves를 더하여 return 합니다.