새소식

Algorithm/BOJ

(JAVA) [BOJ]백준 14891번, 톱니바퀴

  • -
728x90

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

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴

www.acmicpc.net

 

14891, 톱니바퀴

📌 난이도 : Gold 5

📌 알고리즘 : 구현

 

이번 문제는 생각할게 많은 구현문제다.회전할 톱니바퀴와 방향이 주어졌을 때, 모든 톱니바퀴의 맞닿는 좌측과 우측을 모두 조회해야 한다.

 

🧩 프로세스

📚 초기화 및 선언

: 톱니바퀴의 12시방향부터 4개를 순서대로 입력받아 넣어준다. (int)

public static void input() throws IOException {
    wheels = new int[4][8]; // 톱니바퀴 상태 입력
    for (int i = 0; i < 4; i++) {
        String s = br.readLine();
        for (int j = 0; j < 8; j++) {
            wheels[i][j] = s.charAt(j) - '0';
        }
    }

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

 

📚 구현

: K번만큼 회전할 톱니바퀴와 회전방향을 입력받고 비교한다.

먼저 회전할 톱니바퀴를 기준으로 왼쪽에 있는 톱니바퀴의 좌측 부분을 비교한다.

같은 극이면 이어지는 톱니바퀴들이 움직이지 않기 때문에 조회를 멈춘다.

같은 극이 아니라면, 해당 톱니바퀴의 회전방향은 j의 짝수 여부에 따라 바뀐다. 이는 j가 짝수인 경우에는 해당 톱니바퀴와 인접해 있지 않기 때문에 같은 방향으로 회전시키면 되는 것이다.

// 톱니바퀴 좌측 비교
for (int j = 0; n != 0 && j < n; j++) {
    // 주어진 톱니바퀴와 방향을 기준으로 톱니바퀴 좌측 비교
    if (wheels[n - j][6] != wheels[n - j - 1][2])
        // j가 짝수면 다른 방향, 홀수면 같은 방향
        isTurn[n - j - 1] = j % 2 == 0 ? -d : d; 
    else
        // 같은 극이면 움직이지 않움
        break;
}

 

오른쪽도 마찬가지로 비교한다.

// 톱니바퀴 우측 비교
for (int j = 0; n != 3 && j < 4 - n - 1; j++) {
    // 주어진 톱니바퀴와 방향을 기준으로 톱니바퀴 우측 비교
    if (wheels[n + j][2] != wheels[n + j + 1][6])
        // j가 짝수면 다른 방향, 홀수면 같은 방향
        isTurn[n + j + 1] = j % 2 == 0 ? -d : d;
    else
        // 같은 극이면 움직이지 않움
        break;
}

 

이렇게 모든 톱니바퀴의 회전 방향을 정했으면 순서대로 톱니바퀴 배열의 값을 옮기면서 회전시키면 된다.

// 반시계방향
private static void goBack(int n) {
    int temp = wheels[n][0];
    for (int i = 0; i <= 6; i++)
        wheels[n][i] = wheels[n][i + 1];
    wheels[n][7] = temp;
}

// 시계방향
private static void goTurn(int n) {
    int temp = wheels[n][7];
    for (int i = 6; i >= 0; i--)
        wheels[n][i + 1] = wheels[n][i];
    wheels[n][0] = temp;
}

 

마지막으로 12시방향의 톱니바퀴의 극에 따라 점수를 계산해주면 끝!

int result = 0;	// 점수
for (int i = 0; i < 4; i++) {
    if(wheels[i][0] == 1)
        result += Math.pow(2, i);	// i번째 톱니바퀴 점수 : 2^i
}

System.out.println(result);

 

 

✅ 전체 코드

: 비교와 값을 방향에 따라 바꿔줘야 하는 과정을 생각하기 어려웠던 문제 !

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

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int[][] wheels;
    static int K;
    public static void main(String[] args) throws IOException {
        input();
        process();
    }

    public static void input() throws IOException {
        wheels = new int[4][8]; // 톱니바퀴 상태 입력
		for (int i = 0; i < 4; i++) {
			String s = br.readLine();
			for (int j = 0; j < 8; j++) {
				wheels[i][j] = s.charAt(j) - '0';
			}
		}

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

    public static void process() throws IOException {
        for (int i = 0; i < K; i++) {
            st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken()) - 1;   // 회전할 톱니 번호
            int d = Integer.parseInt(st.nextToken());       // 회전 방향 ( 1 => 시계, -1 => 반시계)
            int isTurn[] = new int[4]; // 회전 여부 저장
            isTurn[n] = d;

            // 톱니바퀴 좌측 비교
            for (int j = 0; n != 0 && j < n; j++) {
                // 주어진 톱니바퀴와 방향을 기준으로 톱니바퀴 좌측 비교
                if (wheels[n - j][6] != wheels[n - j - 1][2])
                    // j가 짝수면 다른 방향, 홀수면 같은 방향
                    isTurn[n - j - 1] = j % 2 == 0 ? -d : d; 
                else
                    // 같은 극이면 움직이지 않움
                    break;
            }

            // 톱니바퀴 우측 비교
            for (int j = 0; n != 3 && j < 4 - n - 1; j++) {
                // 주어진 톱니바퀴와 방향을 기준으로 톱니바퀴 우측 비교
                if (wheels[n + j][2] != wheels[n + j + 1][6])
                    // j가 짝수면 다른 방향, 홀수면 같은 방향
                    isTurn[n + j + 1] = j % 2 == 0 ? -d : d;
                else
                    // 같은 극이면 움직이지 않움
                    break;
            }

            // 톱니바퀴 회전
            for (int j = 0; j < 4; j++) {
                // 시계방향 회전
                if(isTurn[j] == 1) 
                    goTurn(j);
                // 반시계방향 회전
                else if(isTurn[j] == -1) 
                    goBack(j);
            }
        }

        int result = 0;	// 점수
		for (int i = 0; i < 4; i++) {
			if(wheels[i][0] == 1)
				result += Math.pow(2, i);	// i번째 톱니바퀴 점수 : 2^i
		}

		System.out.println(result);
    }

    // 반시계방향
	private static void goBack(int n) {
		int temp = wheels[n][0];
		for (int i = 0; i <= 6; i++)
			wheels[n][i] = wheels[n][i + 1];
		wheels[n][7] = temp;
	}
 
	// 시계방향
	private static void goTurn(int n) {
		int temp = wheels[n][7];
		for (int i = 6; i >= 0; i--)
			wheels[n][i + 1] = wheels[n][i];
		wheels[n][0] = temp;
	}
}

 

728x90
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.