[BOJ/Java] 14891: 톱니바퀴

2025. 6. 11. 19:52·Problem Solving/BOJ

문제

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

8개의 톱니를 가진 톱니바퀴 4개가 일렬로 놓여져 있다. 톱니는 N 또는 S극이다.

톱니바퀴를 K번 회전시키려고 한다. 1번 회전은 한 칸을 기준으로 한다. 회전은 시계 방향, 반시계 방향이 있다.

톱니바퀴를 회전시킬 때는, 회전시킬 톱니바퀴와 방향을 결정해야 한다.

톱니바퀴 A가 회전할 때, 그 옆에 있는 톱니바퀴 B의 서로 맞닿은 톱니의 극이 다르다면, B는 A와 반대 방향으로 회전한다.

초록색 점선으로 표시된 부분이 맞닿은 부분이다. 만약, 이 그림에서 3번 톱니 바퀴가 시계 방향으로 회전한다면, 4번 톱니바퀴는 반시계 방향으로 회전하게 된다.

K번의 톱니바퀴 회전이 주어지면, 최종 톱니바퀴의 상태는 어떻게 변할지 구해야 한다.

 

풀이

톱니바퀴의 정보는 2차원 배열에 담았다. `wheels[i][j]`는 `i`번째 톱니바퀴의 `j`번째 톱니에 대한 정보를 담았다.

 

우선 톱니바퀴를 회전시키는 로직인 `rotateWheel` 함수를 작성해주었다. `rotateWheel`은 회전시킬 톱니바퀴와 방향을 받아 톱니바퀴를 시계 방향 혹은 반시계 방향으로 회전시킨다.

💡 Java의 `Collections.rotate(List<?> list, int distance)` 메서드로 List 객체를 회전시킬 수 있다. 이를 이용하면 배열을 쉽게 회전시킬 수 있다. `distance`의 양만큼 회전하고, 음수일 땐 역방향으로 회전시킨다. 다만, in-place 연산이기 때문에 원본을 유지하려면 복사해서 회전시켜야 한다.

아래와 같이 직접 구현하지 않고도 회전시킬 수 있다.

static void rotateWheel(int num, int dir) {
    List<Integer> wheel = new ArrayList<>();
    for (int i = 0; i < 8; i++) {
        wheel.add(wheels[num][i]);
    }
    Collections.rotate(wheel, dir == 1 ? 1 : -1);
    for (int i = 0; i < 8; i++) {
        wheels[num][i] = wheel.get(i);
    }
}

 

그 다음, `k`번에 걸쳐 회전시킬 톱니바퀴와 방향이 주어지면, 해당 톱니바퀴를 기준으로 다른 톱니바퀴의 회전 여부도 결정해주었다. 처음 구현했을 땐, 회전시킬 톱니바퀴에 대한 정보를 바탕으로, 양옆의 톱니바퀴를 바로 회전시키는 로직으로 작성했었는데, 그렇게 되면 회전된 톱니바퀴를 기준으로 그 다음 톱니바퀴의 회전 여부가 결정되어버려 문제의 조건에 맞지 않게 된다. 회전시킬 톱니바퀴를 찾은 뒤, 한 번에 회전시켜야 문제의 조건에 맞게 구현할 수 있다. (문제를 꼼꼼하게 이해하는 게 제일 어렵다는 걸 다시 한번 느낀다..)

 

코드

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

public class Main {
    static int k;
    static int[][] wheels;
    static int score;
    static final int FIRST = 0, SECOND = 1, THIRD = 2, FOURTH = 3;

    public static void main(String[] args) throws IOException {
        // 8개의 톱니(N, S)를 가진 4개의 톱니바퀴
        // K번 회전한다.
        // 톱니바퀴를 회전시키기 전, 맞닿은 톱니의 극이 다르면 맞닿은 톱니바퀴가
        // 반대 방향으로 회전
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        wheels = new int[4][8];
        for (int i = 0; i < 4; i++) {
            String info = br.readLine();
            for (int j = 0; j < 8; j++) {
                wheels[i][j] = info.charAt(j) - '0';
            }
        }

        // k번 회전한다.
        k = Integer.parseInt(br.readLine());
        while (k-- > 0) {
            st = new StringTokenizer(br.readLine());
            int num = Integer.parseInt(st.nextToken()) - 1;
            int dir = Integer.parseInt(st.nextToken());
            // 회전시키기 전, 맞닿은 톱니바퀴들의 회전 여부를 판단
            // 한 번에 회전
            List<int[]> rotateList = new ArrayList<>();
            rotateList.add(new int[]{num, dir});
            int curDir = dir;
            switch (num) {
                case FIRST: {
                    if (wheels[FIRST][2] != wheels[SECOND][6]) {
                        curDir *= -1;
                        rotateList.add(new int[]{SECOND, curDir});
                        if (wheels[SECOND][2] != wheels[THIRD][6]) {
                            curDir *= -1;
                            rotateList.add(new int[]{THIRD, curDir});
                            if (wheels[THIRD][2] != wheels[FOURTH][6]) {
                                curDir *= -1;
                                rotateList.add(new int[]{FOURTH, curDir});
                            }
                        }
                    }
                    break;
                }
                case SECOND: {
                    if (wheels[SECOND][6] != wheels[FIRST][2]) { // 왼쪽
                        curDir *= -1;
                        rotateList.add(new int[]{FIRST, curDir});
                    }
                    curDir = dir;
                    if (wheels[SECOND][2] != wheels[THIRD][6]) { // 오른쪽
                        curDir *= -1;
                        rotateList.add(new int[]{THIRD, curDir});
                        if (wheels[THIRD][2] != wheels[FOURTH][6]) {
                            curDir *= -1;
                            rotateList.add(new int[]{FOURTH, curDir});
                        }
                    }
                    break;
                }
                case THIRD: {
                    if (wheels[THIRD][6] != wheels[SECOND][2]) { // 왼쪽 전파
                        curDir *= -1;
                        rotateList.add(new int[]{SECOND, curDir});
                        if (wheels[SECOND][6] != wheels[FIRST][2]) {
                            curDir *= -1;
                            rotateList.add(new int[]{FIRST, curDir});
                        }
                    }
                    curDir = dir;
                    if (wheels[THIRD][2] != wheels[FOURTH][6]) { // 오른쪽 전파
                        curDir *= -1;
                        rotateList.add(new int[]{FOURTH, curDir});
                    }
                    break;
                }
                case FOURTH: {
                    if (wheels[FOURTH][6] != wheels[THIRD][2]) {
                        curDir *= -1;
                        rotateList.add(new int[]{THIRD, curDir});
                        if (wheels[THIRD][6] != wheels[SECOND][2]) {
                            curDir *= -1;
                            rotateList.add(new int[]{SECOND, curDir});
                            if (wheels[SECOND][6] != wheels[FIRST][2]) {
                                curDir *= -1;
                                rotateList.add(new int[]{FIRST, curDir});
                            }
                        }
                    }
                    break;
                }
            }
            for (int[] r : rotateList) {
                rotateWheel(r[0], r[1]);
            }
        }

        for (int i = 0; i < 4; i++) {
            if (wheels[i][0] == 1) {
                score += (1 << i);
            }
        }
        System.out.println(score);
    }

    static void rotateWheel(int num, int dir) {
        int temp;
        int[] newWheel = new int[8];
        if (dir == 1) { // 시계 방향
            temp = wheels[num][7];
            for (int i = 1; i < 8; i++) {
                newWheel[i] = wheels[num][i - 1];
            }
            newWheel[0] = temp;
        } else {
            temp = wheels[num][0];
            for (int i = 1; i < 8; i++) {
                newWheel[i - 1] = wheels[num][i];
            }
            newWheel[7] = temp;
        }
        wheels[num] = newWheel;
    }
}

 

저작자표시 비영리 동일조건 (새창열림)

'Problem Solving > BOJ' 카테고리의 다른 글

[BOJ/Java] 16236: 아기 상어  (1) 2025.06.14
[BOJ/Java] 16927: 배열 돌리기 2  (1) 2025.06.12
[BOJ/Java] 17143: 낚시왕  (0) 2025.06.11
[BOJ/Java] 17144: 미세먼지 안녕!  (3) 2025.06.10
[BOJ/Java] 14888: 연산자 끼워넣기  (0) 2025.06.09
'Problem Solving/BOJ' 카테고리의 다른 글
  • [BOJ/Java] 16236: 아기 상어
  • [BOJ/Java] 16927: 배열 돌리기 2
  • [BOJ/Java] 17143: 낚시왕
  • [BOJ/Java] 17144: 미세먼지 안녕!
friend5hip
friend5hip
개발 관련 지식이나 기록을 남기고 있습니다.
  • friend5hip
    friend5hip
    friend5hip
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • 컴퓨터공학 (2)
        • 자료구조 (0)
        • 알고리즘 (1)
        • 데이터베이스 (1)
      • Problem Solving (42)
        • BOJ (25)
        • 프로그래머스 (15)
      • 언어 (2)
        • JavaScript (2)
      • 라이브러리 (12)
        • React (12)
      • 개발 (2)
      • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    완전 탐색
    소수 판별
    수학
    구현
    프로그래머스
    집합
    java
    이분 탐색
    순열
    그리디
    백준
    코드트리
    JavaScript
    누적 합
    N과 M
    dfs
    백트래킹
    정렬
    intersection observer
    맵
    삼성 sw 역량테스트
    vite
    BFS
    매개 변수 탐색
    구간 합
    투 포인터
    문자열
    react
    시뮬레이션
    dp
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
friend5hip
[BOJ/Java] 14891: 톱니바퀴
상단으로

티스토리툴바