ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ) 톱니바퀴
    알고리즘/백준 2020. 8. 28. 16:27
    반응형

    톱니바퀴

     

    14891번: 톱니바퀴

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

    www.acmicpc.net

    풀이

     

    생각보다 많이 까다로워서 푸는데 한시간정도 걸렸다.

    가장 오래걸렸던 부분은 회전하기 전에 각 톱니바퀴들의 좌측과 우측의 극을 확인해야한다는 부분이다.

    회전하면서 극을 새롭게 찾으면서 코드를 작성했어서, sholdTurn이라는 boolean 함수를 만들어 움직여야하는지 판별해줬다.

    또한, 처음 입력받는 톱니바퀴의 상태는 가장 처음 인덱스가 문제의 설명처럼 좌측부터 있는 것이 아니라, 12시이 가장 맨 처음으로 주어진다는 것이 왜 이렇게 꼬아놓은거지..? 라고 생각했다.

     

    아무튼 위의 두 과정만 신경써주면 머리가 복잡해질 이유는 없을 것 같다.

    내가 푼 로직은 다음과 같다.

     

    1. 톱니바퀴를 입력받을 때, 0번 인덱스에 톱니바퀴의 가장 왼쪽 상태가 오도록 저장한다. (시계 방향으ㅡ로 두번 돌려줬다. -> 12시가 2번 인덱스로 가게 설정)

    2. 회전 명령이 주어지면, 먼저 1~4 톱니바퀴들이 맞물려있는 상태를 확인한다.

     2-1. standard를 기준으로 좌측의 톱니들을 확인해주고, 오른쪽의 톱니들을 순차적으로 확인해줬다. (이 과정은 하나의 for문으로 해도 될거같다.)

     2-2. 회전 명령을 받은 톱니바퀴를 시계 / 반시계 명령에 따라 움직여줬다.

     2-3. 기준점 좌측의 극이 맞물려 돌아가야 하는 톱니바퀴까지 회전시켜줬다. (만약 시계 방향이 명령이면, 반시계 -> 시계 -> 반시계 이런식)

     2-4. 기준점 우측 방향도 2-3처럼 돌려줬다.

    3. 모든 과정이 끝나고 1~4의 톱니바퀴 top을 확인하면서, S극이면 바퀴 번호에 따라서 2^(n-1) 점을 더해줬다.

     

     

    코드

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
        final static int units = 4, elements =8, turn_right =1, turn_left = -1, left = 0, right =4, top = 2;
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            char[][] gears = new char[units][elements];
            for(int i=0; i<units; i++)  gears[i] = getGearStatus(br.readLine());
            int k = Integer.parseInt(br.readLine());
            int[][] commands = new int[k][2];
            for(int i=0; i<k; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                commands[i][0] = Integer.parseInt(st.nextToken())-1;
                commands[i][1] = Integer.parseInt(st.nextToken());
            }
            br.close();
            solution(gears, commands);
        }
    
        private static char[] getGearStatus(String readLine) {
            char[] gear = readLine.toCharArray();
            gear = turnRight(turnRight(gear));
            return gear;
        }
    
        private static void solution(char[][] gears, int[][] commands) {
            for(int[] command : commands) {
                int standard = command[0];
                gears = turnGears(standard, command[1], gears);
            }
            int score = getScore(gears);
            System.out.println(score);
        }
    
        private static int getScore(char[][] gears) {
            int result =0;
            final char sPole = '1';
            for(int i=0; i<units; i++) {
                if(gears[i][top] == sPole)  result += Math.pow(2,i);
            }
            return result;
        }
    
        private static char[][] turnGears(int standard, int direction, char[][] gears) {
            int prev = direction;
            boolean[] shouldTurn = new boolean[units];
            shouldTurn[standard] = true;
            for(int i=standard; i>0; i--) {
                if(gears[i][left] != gears[i-1][right]) shouldTurn[i-1] = true;
            }
            for(int i=standard; i<units-1; i++) {
                if(gears[i][right] != gears[i+1][left]) shouldTurn[i+1] = true;
            }
            if(direction == turn_left)  gears[standard] = turnLeft(gears[standard]);
            else                        gears[standard] = turnRight(gears[standard]);
    
            for(int i=standard-1; i>=0; i--) {
                if(shouldTurn[i]) {
                    if(prev == turn_left) {
                        gears[i] = turnRight(gears[i]);
                        prev = turn_right;
                    } else {
                        gears[i] = turnLeft(gears[i]);
                        prev = turn_left;
                    }
                } else  break;
            }
            prev = direction;
            for(int i=standard+1; i<units; i++) {
                if(shouldTurn[i]) {
                    if(prev == turn_left) {
                        gears[i] = turnRight(gears[i]);
                        prev = turn_right;
                    } else {
                        gears[i] = turnLeft(gears[i]); 
                        prev = turn_left;
                    }
                } else break;
            }
            return gears;
        }
        private static char[] turnLeft(char[] gear) {
            char[] result = new char[elements];
            for(int i=1; i<elements; i++)   result[i-1] = gear[i];
            result[elements-1] = gear[0];
            return result;
        }
        private static char[] turnRight(char[] gear) {
            char[] result = new char[elements];
            for(int i=0; i<elements-1; i++) result[i+1] = gear[i];
            result[0] = gear[elements-1];
            return result;
        }
    }
    반응형

    '알고리즘 > 백준' 카테고리의 다른 글

    BOJ) 숫자고르기  (0) 2020.08.28
    BOJ) 한 줄로 서기  (0) 2020.08.28
    BOJ) 선분 위의 점  (0) 2020.08.28
    BOJ) 토너먼트  (0) 2020.08.27
    BOJ) 점프  (0) 2020.08.27

    댓글

Designed by Tistory.