2026.05.21
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA
조이스틱을 각 방향으로 움직이면 아래와 같습니다.
▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.
- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

예외 사항 BBAAAAABBB일 때, 10이 나와야 하지만, 12가 출력됨
class Solution {
private int count = 0;
private boolean visited[];
// 최소 거리에 있는 인덱스를 리턴하는 함수
public int nearIndex(String name, int index, int len) {
int right = index;
int rightCnt = 0;
while(true) {
char c = name.charAt(right);
if (c != 'A' && !visited[right]) {
break;
}
right = (right + 1 + len) % len;
rightCnt++;
}
int left = index;
int leftCnt = 0;
while(true) {
char c = name.charAt(left);
if (c != 'A' && !visited[left]) {
break;
}
left = (left - 1 + len) % len;
leftCnt++;
}
count += Math.min(rightCnt, leftCnt);
if (rightCnt < leftCnt) {
visited[right] = true;
return right;
}
else {
visited[left] = true;
return left;
}
}
// 알파벳을 최소 조작으로 변경하는 횟수를 더하는 함수
public void nearAlpha(char c1, char c2) {
int up = 0;
int down = 0;
char upC = c2;
char downC = c2;
while(true) {
if (c1 == upC) break;
upC = (char)('A' + (upC - 'A' + 1) % 26);
up++;
}
while(true) {
if (c1 == downC) break;
downC = (char)('A' + (downC - 'A' - 1 + 26) % 26);
down++;
}
count += Math.min(up, down);
}
public int solution(String name) {
// 시작 문자 만들기
int len = name.length();
visited = new boolean[len];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
sb.append("A");
}
int index = 0;
while(true) {
if (sb.toString().equals(name)) break;
index = nearIndex(name, index, len);
char c1 = name.charAt(index);
char c2 = sb.charAt(index);
nearAlpha(c1, c2);
sb.setCharAt(index, c1);
}
return count;
}
}
for문: 오른쪽으로 전진하다가 방향을 전환하는 구간
next: 연속 A구간이 끝나는 인덱스
goRight: 오른쪽으로 이동한 거리
goLeft: 왼쪽 순환으로 접근했을 때, A가 아닌 첫 번째 문자의 인덱스
class Solution {
public int solution(String name) {
int len = name.length();
// 1. 알파벳 변환 비용
int alphaCost = 0;
for (int i = 0; i < len; i++) {
int up = name.charAt(i) - 'A';
alphaCost += Math.min(up, 26 - up);
}
// 2. 이동 비용
int minMove = len - 1;
for (int i = 0; i < len; i++) {
int next = i + 1;
while (next < len && name.charAt(next) == 'A') next++;
int goRight = i;
int goLeft = len - next;
minMove = Math.min(minMove, Math.min(goRight * 2 + goLeft, goRight + goLeft * 2));
}
return alphaCost + minMove;
}
}