Coding Test/BaekJoon

[백준] 14891번: 톱니바퀴 - java

찬 주 2023. 9. 26. 16:31

문제

https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

 

접근법

문제 그대로 구현하면 되는 쉬운 문제이다. 톱니바퀴를 나타내는 클래스를 하나 만들고, 시계 또는 반시계 방향으로 움직이는 메서드를 만들었다.

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    static Wheel[] wheels = new Wheel[4];
    static int K;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        for (int i = 0; i < 4; i++) {
            int[] tmp = new int[8];
            String s = br.readLine();

            for (int j = 0; j < 8; j++) {
                tmp[j] = s.charAt(j) - '0';
            }

            wheels[i] = new Wheel(i, tmp);
        }

        K = Integer.parseInt(br.readLine());
        for (int i = 0; i < K; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int num = Integer.parseInt(st.nextToken()) - 1;
            int direction = Integer.parseInt(st.nextToken());
            wheels[num].move(direction);
        }

        // 점수 계산
        int score = 0;
        for (int i = 0; i < 4; i++) {
            if (wheels[i].top() == 1) {
                score += Math.pow(2, i);
            }
        }

        System.out.println(score);
    }

    static class Wheel {
        int[] pole;
        int idx, top;
        boolean moved = false;

        public Wheel(int idx, int[] pole) {
            this.idx = idx;
            this.pole = pole;
            this.top = 0;
        }

        private int top() {
            return pole[top];
        }

        private int left() {
            int tmp = top - 2;
            tmp = (tmp < 0) ? tmp + 8 : tmp;

            return pole[tmp];
        }

        private int right() {
            int tmp = top + 2;
            tmp = (tmp > 7) ? tmp - 8 : tmp;

            return pole[tmp];
        }

        private void move(int direction) {
            // 이미 내가 움직인 경우
            if (moved) {
                return;
            }

            moved = true;

            // 왼쪽에 맞닿은 힐이 있는 경우
            if (idx > 0 && wheels[idx - 1].right() != this.left()) {
                wheels[idx - 1].move(-direction);
            }
            // 오른쪽에 맞닿은 힐이 있는 경우
            if (idx < 3 && wheels[idx + 1].left() != this.right()) {
                wheels[idx + 1].move(-direction);
            }

            if (direction == 1) {
                top = (top - 1 < 0) ? 7 : (top - 1);
            } else {
                top = (top + 1 > 7) ? 0 : (top + 1);
            }

            moved = false;
        }
    }
}

 

주의할 점

톱니바퀴 두개가 이렇게 생겼다고 가정하고, 내가 이동할 때마다 맞닿은 부분이 다르다면 해당 톱니바퀴는 반대 방향으로 회전하도록 코드를 작성한다면 두 톱니바퀴는 무한 회전하게 된다. 그래서 나는 flag를 하나 만들어 이미 한번 회전했다면 더 이상 회전하지 않도록 하였다.