baekjoon/Implementation

백준 14891번 : 톱니바퀴 [자바]

Meluu_ 2025. 7. 24. 09:57

 

🧫 문제 분석

 

✔️ 출처

톱니바퀴 골드 5

 

📖 문제

 

전체적인 로직이해는 잘 했는데

실시간 톱니가 회전된 상태에서 N, S를 비교하는게 아니라

회전하기전 상태에서 비교하는건데 이걸 캐치하지 못했다.

 

또한 변동idx값을 따로 저장하는데

-의 경우 8보다 커지면 

+ 8을 해줘도 인덱스가 -로 Array Index Out Of Bounds Exceptions가 터졌다.

 

음수로 변동값을 주었을때 그 값이 배열의 크기를 넘어버리면 안된다.

따라서 해당 변동값 자체도 나눠버리면 된다.

 


🔅 문제 풀이

import java.io.*;
import java.util.*;

public class Main {

    //  14891번 톱니바퀴

    // 시계방향 -1
    // 반시계방향 +1

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[][] arr = new char[4][8];
        int[] dist = new int[4]; // 이동 값

        for (int i = 0; i < 4; i++) {
            arr[i] = br.readLine().toCharArray();
        }

        int K = Integer.parseInt(br.readLine());

        for (int i = 0; i < K; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());

            int idx = Integer.parseInt(st.nextToken()) - 1;
            int dir = Integer.parseInt(st.nextToken()); // 돌아가는 변동 거리로 볼 수 있음

            // 변동값 임시 저장
            int[] tmp = new int[4];

            // 주변 톱니 먼저 회전

            // 왼쪽 파트
            int leftDir = dir;
            for (int j = idx-1; j >= 0; j--) {
                int curLeftIdx = (6 + dist[j + 1] + 8) % 8;
                int nextRightIdx = (2 + dist[j] + 8) % 8;

                if (arr[j+1][curLeftIdx] != arr[j][nextRightIdx]) {
                    tmp[j] = leftDir;
                    leftDir *= -1;

                } else {
                    break;
                }
            }

            // 오른쪽 파트
            int rightDir = dir;
            for (int j = idx + 1; j < 4; j++) {
                int curRightIdx = (2 + dist[j-1] + 8) % 8;
                int nextLeftIdx = (6 + dist[j] + 8) % 8;


                // 서로 다른 극이라면 회전
                if (arr[j-1][curRightIdx] != arr[j][nextLeftIdx]) {
                    tmp[j] = rightDir;
                    rightDir *= -1;

                } else {
                    break;
                }
            }

            for (int j = 0; j < 4; j++) {
                dist[j] += tmp[j];
                dist[j] %= 8; // 변동값이 음수이면서 -8이하로 되는것을 방지
            }

            // 그 후 현재 톱니 회전
            dist[idx] += (dir * - 1);

        }

        int sum = 0;
        // 12시 정각은 0번 인덱스
        for (int i = 0; i < 4; i++) {
            int topIndex = (dist[i] + 8) % 8;

            if (arr[i][topIndex] == '1') {
                sum += 1 << i;
            }
        }

        System.out.println(sum);
    }




}

 

 

 

❗ 오답노트 / 필요한 지식

  1.  원의 인덱스를 구할 경우 음수를 조심하고 변동값이 클 때는 불확실하다면 더 쪼개서 나누자
  2.  문제를 더 꼼꼼히 읽고 알아낸 정보를 확실하게 적자