[백준/BOJ] 14891번 - 톱니바퀴(Python, Java)
· 문제링크
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)