14891번: 톱니바퀴
총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴
www.acmicpc.net
문제 간단 설명
네 개의 톱니바퀴가 존재하며 각 톱니바퀴를 회전시킵니다. 톱니바퀴가 회전할 때 인접한 곳에 있는 톱니바퀴와 만나는 부분의 자석 극이 다르다면 함께 회전하게 됩니다. 톱니바퀴를 여러 번 회전 시킨 후 톱니바퀴의 상태를 확인하는 문제입니다.
문제 풀이
이번 문제도 구현 문제로 톱니바퀴의 모양을 어떻게 코드로 표현하며, 이를 어떻게 회전시키는지 생각할 수 있는지 보는 문제 입니다.
코드
package com.baekjoon.gold;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class Main_BJ_14891_G5_톱니바퀴 {
static List<LinkedList<Integer>> list;
//톱니바퀴를 회전시키는 함수입니다. 톱니바퀴의 idx(몇 번 톱니바퀴인지.), 방향을 받아 회전시킵니다.
static void turnGear(int idx, int cmd) {
if(cmd==1) {
LinkedList<Integer> now = list.get(idx);
now.addFirst(now.getLast());
now.removeLast();
} else {
LinkedList<Integer> now = list.get(idx);
now.addLast(now.getFirst());
now.removeFirst();
}
}
public static void main(String[] args) throws Exception{
list = new ArrayList<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//톱니바퀴의 정보를 입력받아 LinkedList에 입력해주었습니다.
for (int i = 0; i < 4; i++) {
list.add(new LinkedList<>());
String str = br.readLine();
for (int j = 0; j < 8; j++) {
list.get(i).add(str.charAt(j)-'0');
}
}
int n = Integer.parseInt(br.readLine());
StringTokenizer st;
//명령어를 하나씩 받으며 톱니바퀴 회전을 시작합니다.
for (int i = 0; i < n; i++) {
//톱니바퀴의 회전 여부를 판단하고 바로 회전을 시키게 되면 다음 판단에 영향을 줄 수 있기 떄문에
//회전의 여부를 담아놓고 해당 시퀀스가 끝날 때 한번에 회전시켜주기 위한 배열들입니다.
boolean[] check = new boolean[4];
int[] direction = new int[4];
st = new StringTokenizer(br.readLine());
int idx = Integer.parseInt(st.nextToken())-1; //톱니바퀴는 1번부터 시작하기 때문에 0부터 시작하는 배열과 맞추어 주기 위해 -1을 해주었습니다.
int cmd = Integer.parseInt(st.nextToken());
//0번, 3번 톱니바퀴일 경우 끝에 있으므로 가장 인접한 톱니부터 확인하였습니다.
//if else를 통해서 인접한 부분이 같지않다면 바로 종료를 시켜주는 방식으로 진행하였습니다.
if(idx == 0) {
//각 톱니바퀴들의 맞닿는 부분의 극이 같은지 다른지 판단하여 다르다면 회전여부를 체크해주는 것을
//반복합니다.
if(list.get(0).get(2)!=list.get(1).get(6)) {
check[1] = true;
direction[1] = cmd*-1;
if(list.get(1).get(2)!=list.get(2).get(6)) {
check[2] = true;
direction[2] = cmd;
if(list.get(2).get(2)!=list.get(3).get(6)) {
check[3] = true;
direction[3] = cmd*-1;
}
}
}
check[idx] = true;
direction[idx] = cmd;
} else if(idx == 3) {
if(list.get(3).get(6)!=list.get(2).get(2)) {
check[2] = true;
direction[2] = cmd*-1;
if(list.get(2).get(6)!=list.get(1).get(2)) {
check[1] = true;
direction[1] = cmd;
if(list.get(1).get(6)!=list.get(0).get(2)) {
check[0] = true;
direction[0] = cmd*-1;
}
}
}
check[idx] = true;
direction[idx] = cmd;
//1, 2번 톱니바퀴는 각각 양쪽의 톱니바퀴를 확인하며 회전 여부를 체크합니다.
} else if(idx == 1) {
if(list.get(1).get(6)!=list.get(0).get(2)) {
check[0] = true;
direction[0] = cmd*-1;
}
if(list.get(1).get(2)!=list.get(2).get(6)) {
check[2] = true;
direction[2] = cmd*-1;
if(list.get(2).get(2)!=list.get(3).get(6)) {
check[3] = true;
direction[3] = cmd;
}
}
check[idx] = true;
direction[idx] = cmd;
} else if(idx == 2){
if(list.get(2).get(2)!=list.get(3).get(6)) {
check[3] = true;
direction[3] = cmd*-1;
}
if(list.get(2).get(6)!=list.get(1).get(2)) {
check[1] = true;
direction[1] = cmd*-1;
if(list.get(1).get(6)!=list.get(0).get(2)) {
check[0] = true;
direction[0] = cmd;
}
}
check[idx] = true;
direction[idx] = cmd;
}
//위의 체크를 통해서 알아낸 회전이 필요한 톱니바퀴들을 회전시켜 줍니다.
for (int j = 0; j < 4; j++) {
if(check[j]) turnGear(j, direction[j]);
}
}
//회전이 끝난 뒤 각 톱니바퀴들의 12시 방향을 확인한 뒤 점수를 부여해줍니다.
int res = 0;
res += list.get(0).get(0) == 0 ? 0 : 1;
res += list.get(1).get(0) == 0 ? 0 : 2;
res += list.get(2).get(0) == 0 ? 0 : 4;
res += list.get(3).get(0) == 0 ? 0 : 8;
//출력!
System.out.println(res);
}
}
'Coding Test > Baekjoon' 카테고리의 다른 글
[백준] 15683 감시, java (0) | 2023.04.11 |
---|---|
[백준] 21608 상어 초등학교, java (0) | 2023.04.08 |
[백준] 14888 연산자 끼워넣기, java (0) | 2023.04.04 |
[백준] 14503 로봇 청소기, java (0) | 2023.04.03 |
[백준] 14499 주사위 굴리기, java (0) | 2023.04.02 |