PS/백준

[백준/BOJ] 14891번 - 톱니바퀴(Python, Java)

행복한라이언 2023. 9. 22. 21:14
728x90
반응형

· 문제링크

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

 

14891번: 톱니바퀴

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

www.acmicpc.net

· 핵심

1. 맞물린 톱니바퀴의 상태 확인하기

→ 12시방향(인덱스 0번)으로 가정한 상태에서....

    「1번 톱니바퀴의 인덱스 2번 = 2번 톱니바퀴의 인덱스 6번」 확인

    2번 톱니바퀴의 인덱스 2번 = 3번 톱니바퀴의 인덱스 6번 확인

    3번 톱니바퀴의 인덱스 2번 = 4번 톱니바퀴의 인덱스 6번 확인

2. check 도입하기

→ 예를 들어 3번 톱니바퀴를 시계방향 회전 시키고 3번 톱니바퀴의 인덱스 2번 = 4번 톱니바퀴의 인덱스 6번」 가 다른 경우 4번 톱니바퀴를 봐야한다. 3번 톱니바퀴를 돌렸다고 체크하지 않으면 4번 톱니바퀴에서 3번 톱니바퀴를 확인했을 때 인덱스가 다르므로 또 3번 톱니바퀴를 돌리게 된다.(재귀로 구현해서 무한에 빠) 따라서 3번 톱니바퀴를 돌렸다고 체크를 해야 4번 톱니바퀴에서 3번을 또 돌리는 일이 없게 된다.

→ 돌린 톱니바퀴는 0 에서 1로 변경

→ 1로 된 톱니바퀴는 이미 돌아간 톱니바퀴이므로 연쇄적으로 톱니바퀴가 돌아갈 때 고려하지 않아도 되며 0인 톱니바퀴만 고려하면 된다.

3. cmd는 시계방향의 1과 반시계 방향의 -1이 존재

연쇄적으로 톱니가 돌 경우 -cmd 처리


· 코드(Java)

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

public class Main {
    public static final int MAX_K = 100;
    //
    public static String[] ts = new String[5];
    public static int[][] cmds = new int[MAX_K][2];
    public static int[] check = new int[5];
    // 반시계 회전
    public static String ccw(String t) {
        char temp = t.charAt(0);
        StringBuilder rotated = new StringBuilder(t.substring(1));
        rotated.append(temp);
        return rotated.toString();
    }
    // 시계 회전
    public static String cw(String t) {
        char temp = t.charAt(t.length() - 1);
        StringBuilder rotated = new StringBuilder(temp + t.substring(0, t.length() - 1));
        return rotated.toString();
    }
    // 톱니번호에 따른 회전
    public static String t1Simulate(int cmd){
        check[1] = 1;

        if(check[2] == 0 && ts[1].charAt(2) != ts[2].charAt(6)){
            ts[2] = t2Simulate(-cmd);
        }

        if (cmd == 1) {
            ts[1] = cw(ts[1]);
        } else {
            ts[1] = ccw(ts[1]);
        }
        return ts[1];
    }
    public static String t2Simulate(int cmd){
        check[2] = 1;

        if(check[3] == 0 && ts[2].charAt(2) != ts[3].charAt(6)){
            ts[3] = t3Simulate(-cmd);
        }
        if(check[1] == 0 && ts[2].charAt(6) != ts[1].charAt(2)){
            ts[1] = t1Simulate(-cmd);
        }
        if (cmd == 1) {
            ts[2] = cw(ts[2]);
        } else {
            ts[2] = ccw(ts[2]);
        }  
        return ts[2];
    }
    public static String t3Simulate(int cmd){
        check[3] = 1;

        if(check[2] == 0 && ts[3].charAt(6) != ts[2].charAt(2)){
            ts[2] = t2Simulate(-cmd);
        }
        if(check[4] == 0 && ts[3].charAt(2) != ts[4].charAt(6)){
            ts[4] = t4Simulate(-cmd);
        }
        if (cmd == 1) {
            ts[3] = cw(ts[3]);
        } else {
            ts[3] = ccw(ts[3]);
        }
        return ts[3];
    }
    public static String t4Simulate(int cmd){
        check[4] = 1;

        if(check[3] == 0 && ts[4].charAt(6) != ts[3].charAt(2)){
            ts[3] = t3Simulate(-cmd);
        }

        if (cmd == 1) {
            ts[4] = cw(ts[4]);
        } else {
            ts[4] = ccw(ts[4]);
        }
        return ts[4];
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 1; i <= 4; i++) { // 톱니바퀴 번호 1부터 4까지 사용
            StringTokenizer st = new StringTokenizer(br.readLine());
            ts[i] = st.nextToken();
        }
        StringTokenizer st = new StringTokenizer(br.readLine());
        int k = Integer.parseInt(st.nextToken()); 
        for (int i = 0; i < k; i++) {
            st = new StringTokenizer(br.readLine());
            cmds[i][0] = Integer.parseInt(st.nextToken()); // cmds[i][0]에 저장
            cmds[i][1] = Integer.parseInt(st.nextToken()); // cmds[i][1]에 저장
        }
    
        for(int i = 0; i < k; i++){
            check = new int[]{0, 0, 0, 0, 0};
            int num = cmds[i][0];
            int cmd = cmds[i][1];
            if (num == 1)
                t1Simulate(cmd);
            else if (num == 2)
                t2Simulate(cmd);
            else if (num == 3)
                t3Simulate(cmd);
            else
                t4Simulate(cmd);
        }
        int sum_val = 0;
        for(int i = 1; i < 5; i++){
            if (ts[i].charAt(0) == '1'){
                 sum_val += Math.pow(2, i - 1);
            }
        }
        System.out.print(sum_val);
    }
}

· 코드(Python)

# 12시방향의 상태 : 인덱스 0번으로 정의!
ts = ['인덱스맞추기용'] + [input() for _ in range(4)]
k = int(input())
cmds = [list(map(int, input().split())) for _ in range(k)]

# 반시계 회전
def ccw(t: str):
    temp = t[0]
    t = t[1:] + temp
    return t

# 시계 회전 
def cw(t: str):
    temp = t[-1]
    t = temp + t[:-1]
    return t

# 톱니바퀴 번호에 따른 다른 톱니 회전 파악하기
def t1_simulate(cmd):
    check[1] = 1
    
    if check[2] == 0 and ts[1][2] != ts[2][6]:
        ts[2] = t2_simulate(-cmd)
        
    if cmd == 1:
        ts[1] = cw(ts[1])
    else: 
        ts[1] = ccw(ts[1])
        
    return ts[1]


def t2_simulate(cmd):
    check[2] = 1

    if check[3] == 0 and ts[2][2] != ts[3][6]:
        ts[3] = t3_simulate(-cmd)
    if check[1] == 0 and ts[2][6] != ts[1][2]:
        ts[1] = t1_simulate(-cmd)
    
    if cmd == 1:
        ts[2] = cw(ts[2])
    else: 
        ts[2] = ccw(ts[2])
        
    
    return ts[2]


def t3_simulate(cmd):
    check[3] = 1
    
    if check[2] == 0 and ts[3][6] != ts[2][2]:
        ts[2] = t2_simulate(-cmd)
    if check[4] == 0 and ts[3][2] != ts[4][6]:
        ts[4] = t4_simulate(-cmd)

    if cmd == 1:
        ts[3] = cw(ts[3])
    else: 
        ts[3] = ccw(ts[3])
        
    return ts[3]



def t4_simulate(cmd):
    check[4] = 1 
    
    if check[3] == 0 and ts[4][6] != ts[3][2]:
        ts[3] = t3_simulate(-cmd)
        
    if cmd == 1:
        ts[4] = cw(ts[4])
    else: 
        ts[4] = ccw(ts[4])
    
    return ts[4]


for num, cmd in cmds:
    check = [0, 0, 0, 0, 0]
    if num == 1:
        t1_simulate(cmd)
    elif num == 2:
        t2_simulate(cmd)
    elif num == 3:
        t3_simulate(cmd)
    else:
        t4_simulate(cmd)

sum_val = 0
for idx, t in enumerate(ts[1:]):
    if t[0] == '1':
        sum_val += 2**(idx)
        
print(sum_val)
728x90
반응형