[BOJ] 14891. 톱니바퀴 - Simulation

제출일 : 2019-10-14

문제 풀이 시간 : 1H

난이도 : ★★★

Problem

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

Input

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터 시계방향 순서대로 주어진다. N극은 0, S극은 1로 나타나있다.

다섯째 줄에는 회전 횟수 K(1 ≤ K ≤ 100)가 주어진다. 다음 K개 줄에는 회전시킨 방법이 순서대로 주어진다. 각 방법은 두 개의 정수로 이루어져 있고, 첫 번째 정수는 회전시킨 톱니바퀴의 번호, 두 번째 정수는 방향이다. 방향이 1인 경우는 시계 방향이고, -1인 경우는 반시계 방향이다.

Output

총 K번 회전시킨 이후에 네 톱니바퀴의 점수의 합을 출력한다. 점수란 다음과 같이 계산한다.

  • 1번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 1점
  • 2번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 2점
  • 3번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 4점
  • 4번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 8점

Example

input

10101111
01111101
11001110
00000010
2
3 -1
1 1

output

7

Solution & Inpression

Code

언어 : JAVA

메모리 : 14,536 kb

실행시간 : 124 ms

import java.util.*;

public class Main {
    static int[][] wheels;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        wheels = new int[5][8];
        for (int i = 1; i <= 4; i++) {
            String str = sc.next();
            for (int j = 0; j < 8; j++) {
                if (str.charAt(j) == '1')
                    wheels[i][j] = 1; // S극
                else
                    wheels[i][j] = 0; // N극
            }
        }

        int K = sc.nextInt(); // 회전 횟수 K;
        for (int i = 0; i < K; i++) {
            // 톱니바퀴 번호, 방향(1:시계 -1:반시계)
            isspin(sc.nextInt(), sc.nextInt());
        }

        System.out.println(1 * wheels[1][0] 
                         + 2 * wheels[2][0] 
                         + 4 * wheels[3][0] 
                         + 8 * wheels[4][0]);

        sc.close();
    }

    //좌우에 톱니를 회전할 수 있는지 확인.
    private static void isspin(int num, int dir) { 
        //회전이 가능한 톱니번호와 뱡향을 저장
        ArrayList<int[]> list = new ArrayList<>(); 

        list.add(new int[] { num, dir });

        int flag = dir;
        int temp = num;
        int right = wheels[num][2]; //현재 바퀴의 오른쪽값.
        while (temp + 1 <=4) { // 오른쪽에 바퀴가 존재한다면
            if (right != wheels[temp + 1][6]) {//회전이 가능한지 
                temp++;
                flag *= -1;
                right = wheels[temp][2]; 
                list.add(new int[] { temp, flag });
            }
            else
                break;
        }

        flag = dir;
        temp = num;
        int left = wheels[num][6]; //현재 바퀴의 왼쪽값.
        while (temp - 1 >=1) { // 왼쪽에 바퀴가 존재한다면
            if (left != wheels[temp - 1][2]) { //회전이 가능한지
                temp--;
                flag *= -1; //반대방향
                left = wheels[temp][6]; 
                list.add(new int[] { temp, flag });
            }
            else
                break;
        }
        for (int i = 0; i < list.size(); i++) {
            spin(list.get(i)[0], list.get(i)[1]);
        }
    }

    private static void spin(int num, int dir) {
        int[] temp = wheels[num].clone(); // 복사

        if (dir == 1) {// 시계방향이면 >> 오른쪽으로 한칸씩
            for (int i = 1; i < 8; i++) {
                wheels[num][i] = temp[i - 1];
            }
            wheels[num][0] = temp[7];
        } else {// 반시계방향이면 >> 왼쪽으로 한칸씩
            for (int i = 1; i < 8; i++) {
                wheels[num][i - 1] = temp[i];
            }
            wheels[num][7] = temp[0];
        }
    }
}