✔ 조이스틱
문제 분석하기
알파벳을 변경할 때 다음 알파벳으로 이동하는 것을 반복해서 완성할지, 이전 알파벳으로 이동하는 것을 반복해서 완성할지 비교
(다음 알파벳, 이전 알파벳 조이스틱 조작 횟수)
또한 위치를 변경할 때도 왼쪽으로 이동하는 것을 반복할지, 오른쪽으로 이동하는 것을 반복할지 비교
(커서 왼쪽 이동, 커서 오른쪽 이동 조이스틱 조작 횟수)
손으로 풀어보기
- 커서를 이동하면서 알파벳을 완성하기 위한 조이스틱 횟수를 증가
- 다음 알파벳으로 이동하는 것을 반복해서 완성할지, 이전 알파벳으로 이동하는 것을 반복할지 횟수 비교
- 예) B
다음 알파벳으로 이동할 경우 'B' - 'A' = 1
이전 알파벳으로 이동할 경우 26 - 'B' - 'A' = 25
- 커서를 이동하면서 변경할 알파벳을 찾는 조이스틱 횟수를 증가
- 오른쪽으로만 이동할지,
오른쪽으로 갔다가 A를 만난 후 다시 돌아와서 왼쪽으로 이동할지,
왼쪽으로 갔다가 A를 만난 후 다시 돌아와서 오른쪽으로 이동할지 횟수 비교 - 예) BCAAB
오른쪽으로 이동할 경우 B → C → A → A → B = 5
오른쪽으로 갔다가 A를 만난 후 다시 돌아와서 왼쪽으로 이동할 경우 B → C → B → B = 3
왼쪽으로 갔다가 A를 만난 후 다시 돌아와서 오른쪽으로 이동할 경우 B → B → B → C = 3
- 오른쪽으로만 이동할지,
- 두 조이스틱 횟수를 합쳐 반환
4(1+1+2) + 3 = 7
슈도코드 작성하기
name(만들고자 하는 이름)
converse(알파벳 변환 횟수)
move(알파벳 이동 횟수)
for(name의 길이만큼) {
converse += Math.min(다음 알파벳으로 이동하는 것을 반복했을 때의 횟수, 이전 알파벳으로 이동하는 것을 반복했을 때의 횟수)
if(현재 알파벳의 다음 알파벳이 A일 경우) {
endA(마지막 A의 위치 인덱스) = 다음 알파벳의 인덱스
while(다른 알파벳이 나오기 전의 마지막 A를 찾을 때까지) {
endA 증가
}
move = Math.min(A를 넘어 다음 알파벳으로 단순 오른쪽 이동 횟수, 오른쪽으로 갔다가 A를 만난 후 다시 돌아와서 왼쪽으로 이동할 경우)
move = Math.min(A를 넘어 다음 알파벳으로 단순 오른쪽 이동 횟수, 왼쪽으로 갔다가 A를 만난 후 다시 돌아와서 오른쪽으로 이동할 경우)
}
}
return converse + move;
코드 구현하기
/**
* 42860) 조이스틱
*/
public class K002_42860 {
// name(만들고자 하는 이름)
public int solution(String name) {
// converse(알파벳 변환 횟수)
int converse = 0;
// move(알파벳 이동 횟수)
int move = name.length() - 1; // 단순 오른쪽 이동 횟수
for (int i = 0; i < name.length(); i++) {
// 다음 알파벳으로 이동하는 것을 반복했을 때의 횟수, 이전 알파벳으로 이동하는 것을 반복했을 때의 횟수 비교
converse += Math.min(name.charAt(i) - 'A', 26 - (name.charAt(i) - 'A'));
// 현재 알파벳의 다음 알파벳이 A일 경우
if (i < name.length() - 1 && name.charAt(i + 1) == 'A') {
// endA(마지막 A의 위치 인덱스)
int endA = i + 1;
// 다른 알파벳이 나오기 전의 마지막 A를 찾을 때까지
while (endA < name.length() && name.charAt(endA) == 'A') {
// endA 증가
endA++;
}
// A를 넘어 다음 알파벳으로 단순 오른쪽 이동 횟수, 오른쪽으로 갔다가 A를 만난 후 다시 돌아와서 왼쪽으로 이동할 경우 비교
move = Math.min(move, i * 2 + (name.length() - endA));
// A를 넘어 다음 알파벳으로 단순 오른쪽 이동 횟수, 왼쪽으로 갔다가 A를 만난 후 다시 돌아와서 오른쪽으로 이동할 경우 비교
move = Math.min(move, i + (name.length() - endA) * 2);
}
}
// 알파벳 변환 횟수와 알파벳 이동 횟수 합산 반환
return converse + move;
}
// 테스트 케이스
public static void main(String[] args) {
K002_42860 solution = new K002_42860();
String name = "JEROEN";
int result = solution.solution(name);
System.out.println(result);
}
}
'Coding Test > Java 알고리즘 실전' 카테고리의 다른 글
[43162] 네트워크 (0) | 2023.11.08 |
---|---|
[43105] 정수 삼각형 (0) | 2023.11.07 |
[42940] 모의고사 (0) | 2023.11.06 |
[42746] 가장 큰 수 (0) | 2023.11.05 |
[42627] 디스크 컨트롤러 (0) | 2023.11.05 |