조이스틱_복습

하이솝·2026년 9월 8일

코테 · Greedy

목록 보기
2/4

2026.09.08

문제 풀이

1차 실행 오류


66.7/100

실패


실패 원인 분석

name이 A로만 이루어져 있을 때, return cnt - len은 음수를 반환함


import java.util.Set;
import java.util.HashSet;

class Solution {
    public int solution(String name) {
        StringBuilder sb = new StringBuilder();
        Set<Integer> resolved = new HashSet<>(); // 헤결된 인덱스 저장
        int len = name.length();
        for (int i = 0; i < len; i++) {
            sb.append("A");
        }
        
        int idx = 0;
        int cnt = 0;
        while(!sb.toString().equals(name)) {
            char n = name.charAt(idx);
            // 알파벳의 변경
            if (n == 'A') {  // word에서 현재 위치한 자리의 알파벳이 name과 같을 때
            } else if (n <= 78) { // name의 알파벳이 N보다 같거나 작을 때
                cnt += (n - 65);
                sb.setCharAt(idx, n);
            } else { // name의 알파벳이 N보다 클 때
                cnt += (90 - n + 1);
                sb.setCharAt(idx, n);
            }
            resolved.add(idx); // 해결된 인덱스 저장
            
            // 자리 이동
            int leftIdx = idx;
            int leftCnt = 0;
            while(true) { // 왼쪽으로 이동
                leftIdx = (leftIdx - 1 < 0) ? (len - 1) : (leftIdx - 1);
                leftCnt++;
                if (!resolved.contains(leftIdx) && name.charAt(leftIdx) != 'A' || leftCnt >= len) {
                    break;
                }
            }
            int rightIdx = idx;
            int rightCnt = 0;
            while(true) { // 오른쪽으로 이동
                rightIdx = (rightIdx + 1) % len;
                rightCnt++;
                if (!resolved.contains(rightIdx) && name.charAt(rightIdx) != 'A' || rightCnt >= len) {
                    break;
                }
            }
            cnt += Math.min(leftCnt, rightCnt);
            idx = (leftCnt < rightCnt) ? leftIdx : rightIdx;
        }
        return cnt - len;
    }
}

2차 실행 오류


소요 시간: 1시간 36분


74.1/100

실패


실패 원인 분석

BBBAAAAAB 일 때 8, BBAAAAABBB 일 때 10이 나와야 한다.
그러나 leftCnt == rightCnt 일 때 각각 왼쪽 오른쪽을 택하며 갈린다.
따라서 leftCnt == rightCnt 일 때 양쪽 경우의 수를 모두 고려해야 한다.


import java.util.Set;
import java.util.HashSet;

class Solution {
    public int solution(String name) {
        StringBuilder sb = new StringBuilder();
        Set<Integer> resolved = new HashSet<>(); // 헤결된 인덱스 저장
        int len = name.length();
        for (int i = 0; i < len; i++) {
            sb.append("A");
        }
        
        int idx = 0;
        int cnt = 0;
        int leftIdx = idx;
        int rightIdx = idx;
        int leftCnt = 0;
        int rightCnt = 0;
        while(!sb.toString().equals(name)) {
            cnt += Math.min(leftCnt, rightCnt);
            idx = (leftCnt < rightCnt) ? leftIdx : rightIdx;
            char n = name.charAt(idx);
            // 알파벳의 변경
            if (n == 'A') {  // word에서 현재 위치한 자리의 알파벳이 name과 같을 때
            } else if (n <= 78) { // name의 알파벳이 N보다 같거나 작을 때
                cnt += (n - 65);
                sb.setCharAt(idx, n);
            } else { // name의 알파벳이 N보다 클 때
                cnt += (90 - n + 1);
                sb.setCharAt(idx, n);
            }
            resolved.add(idx); // 해결된 인덱스 저장
            
            // 자리 이동
            leftIdx = idx;
            leftCnt = 0;
            while(true) { // 왼쪽으로 이동
                leftIdx = (leftIdx - 1 < 0) ? (len - 1) : (leftIdx - 1);
                leftCnt++;
                if (!resolved.contains(leftIdx) && name.charAt(leftIdx) != 'A' || leftCnt >= len) {
                    break;
                }
            }
            rightIdx = idx;
            rightCnt = 0;
            while(true) { // 오른쪽으로 이동
                rightIdx = (rightIdx + 1) % len;
                rightCnt++;
                if (!resolved.contains(rightIdx) && name.charAt(rightIdx) != 'A' || rightCnt >= len) {
                    break;
                }
            }
        }
        return cnt;
    }
}

AI 코드


코드 분석

양쪽 다 가야 하는데 몸은 하나 뿐이라
한쪽을 갔다 돌아와서 다른 쪽으로 가는 수밖에 없음

방향을 세번, 네번 바꾸는 경로는 같은 구간을 여러번 밟게 되므로
무조건 더 많이 이동할 수 밖에 없음


class Solution {
    public int solution(String name) {
        int len = name.length();
        int answer = 0;
        int move = len - 1; // 되돌아오지 않고 오른쪽 끝까지 직진하는 경우

        for (int i = 0; i < len; i++) {
            // 1) 알파벳 변경 비용 (위로 올리기 vs 아래로 내리기)
            answer += Math.min(name.charAt(i) - 'A', 'Z' - name.charAt(i) + 1);

            // 2) i 다음에 이어지는 'A' 구간을 건너뛴다
            int next = i + 1;
            while (next < len && name.charAt(next) == 'A') next++;

            // 오른쪽 i번까지 갔다가 → 0으로 되돌아와서 → 왼쪽 next번까지 (오른쪽 구간을 두 번 걸음)
			move = Math.min(move, i * 2 + (len - next));
			// 왼쪽 next번까지 갔다가 → 0으로 되돌아와서 → 오른쪽 i번까지 (왼쪽 구간을 두 번 걸음)
			move = Math.min(move, (len - next) * 2 + i);
        }
        return answer + move;
    }
}

문제 풀이 후기

진짜 너무 어려웠다.
내 코드를 실행 하기 전에 테스트 코드를 전부 통과해서
당연히 통과할 줄 알았는데 그게 아니었다.

지금 내 실력으로는 74.1점이 최대 점수인 것 같다.

AI 코드는 언제 봐도 감탄만 나왔는데, 오늘은 코드를 보고
왜이렇게 짧지? 하면서 보다가 이게 무슨 코드인가 해석 하는데에
꽤나 힘이 들었다.

코딩을 하는 데에 있어서 사고력이 정말 중요한 것 같다.
코드를 설계하고 어떤 방법으로 풀어 나갈 것인가 하는 그런 사고력이
앞으로 내가 코딩 실력을 키우는 데에 중요한 능력이 될 것 같다.

0개의 댓글