[백준/14891] 톱니바퀴(Java)

지니·2021년 4월 21일
0

Algorithm_Simulation

목록 보기
5/9

Question


문제 해설

  1. 4개의 톱니바퀴 존재, 각 톱니에는 N극과 S극이 나타나져있음
  2. 톱니바퀴가 회전할 때, 서로 맞닿은 극에 따라서 옆에 있는 톱니바퀴 회전 여부 결정
    • 서로 맞닿은 톱니의 극이 다르다면, 기준이 되는 쪽과 회전한 방향과 반대방향으로 회전
    • 극이 같다면, 회전하지 않음
    • 회전하지 않는 톱니바퀴가 존재하면 그 뒤로는 모두 회전하지 않음
  3. 회전시키는 방법이 주어지면, 이에 해당하는 최종 톱니바퀴의 상태는?



Solution

풀이 접근 방법

  1. 톱니바퀴를 배열로 풀었을 때
    • 오른쪽 톱니바튀와 맞닿은 칸은 2번 인덱스
    • 왼쪽 톱니바퀴와 맞닿은 칸은 6번 인덱스
  2. 돌리는 톱니바퀴 기준 왼쪽과 오른쪽을 돌면서 회전 여부 판별

정답 코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;

public class Main {
  static int K;
  static LinkedList<Integer>[] gears;

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

    gears = new LinkedList[4];

    for (int i = 0; i < 4; i++) {
      String[] info = br.readLine().split("");
      gears[i] = new LinkedList<Integer>();

      for (int j = 0; j < 8; j++) {
        gears[i].add(Integer.valueOf(info[j]));
      }
    }

    K = Integer.valueOf(br.readLine());

    for (int i = 0; i < K; i++) {
      String[] info = br.readLine().split(" ");
      int[] dir = checkDir(Integer.valueOf(info[0]) - 1, Integer.valueOf(info[1]));

      turnGear(dir);
    }

    bw.write(calcGear() + "\n");
    bw.flush();
    bw.close();
  }

  static int[] checkDir(int gNum, int dir) {
    // 해당 톱니바퀴가 회전해야하는 방향 입력
    int[] dirArr = new int[4];
    dirArr[gNum] = dir;

    // 기준 왼쪽 탐색
    for (int i = gNum + 1; i < 4; i++) {
      int rightDir = dirArr[i - 1];
      int right = gears[i - 1].get(2);
      int left = gears[i].get(6);

      if (right == left)
        // 나타내는 극이 같으면 그 이후에 있는 톱니바뀌는 돌아가지 않기 때문에 반복문 탈출
        break;
      else
        // 나타내는 극이 서로 다르면 반대 방향 입력
        dirArr[i] = rightDir == 1 ? -1 : 1;
    }

    // 기준 왼쪽 탐색
    for (int i = gNum - 1; i >= 0; i--) {
      int leftDir = dirArr[i + 1];
      int left = gears[i + 1].get(6);
      int right = gears[i].get(2);

      if (right == left)
        break;
      else
        dirArr[i] = leftDir == 1 ? -1 : 1;
    }

    return dirArr;
  }

  static void turnGear(int[] dir) {
    for (int i = 0; i < 4; i++) {
      switch (dir[i]) {
      case 1:
        // 시계방향 : 맨 뒤에 있는거 맨 앞으로
        gears[i].addFirst(gears[i].removeLast());
        break;
      case -1:
        // 반시계방향 : 맨 앞에 있는거 맨 뒤로
        gears[i].addLast(gears[i].removeFirst());
        break;
      default:
        break;
      }
    }
  }

  static int calcGear() {
    int sum = 0;

    for (int i = 0; i < 4; i++) {
      int value = gears[i].get(0);

      if (value == 1)
        sum += (int) Math.pow(2, i);
    }

    return sum;
  }
}

profile
코.빠.죄.아 (코딩에 빠진 게 죄는 아니잖아..!)

0개의 댓글