백준 15662 - 톱니바퀴 (2)
Updated:
Java
15662 번 - 톱니바퀴 (2)
문제
접근 방법
톱니바퀴 하나를 Deque
을 사용하고, List<Deque>
을 통해 전체 톱니바퀴를 구현하였다.
톱니바퀴의 양옆을 비교하는 방식은 다음과 같다.
-
왼쪽 비교
현재 톱니바퀴의 Deque에 뒤에서 1개를 뺀다. 왼쪽 톱니바퀴의 Deque에 앞에서 2개를 뺀다.현재 톱니바퀴 Deque의 Last와 왼쪽 톱니바퀴 First가 다른지 확인
-
오른쪽 비교 현재 톱니바퀴의 Deque에 앞에서 2개를 뺀다. 왼쪽 톱니바퀴의 Deque에 뒤에서 1개를 뺀다.
현재 톱니바퀴 Deque의 First와 왼쪽 톱니바퀴 Last가 다른지 확인
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, result;
static List<Deque<Integer>> gear;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
n = stoi(br.readLine()); // 톱니바퀴의 개수
// 톱니바퀴 상태 입력
String str;
gear = new ArrayList<>();
// 톱니바퀴 개수만큼 입력 받는다.
for(int i = 0; i < n; i++) {
str = br.readLine();
gear.add(new ArrayDeque<Integer>());
// 톱니는 8개
for(int j = 0; j < 8; j++) {
gear.get(i).add(str.charAt(j) - '0');
}
}
// 톱니바퀴 회전
int k = stoi(br.readLine());
int idx, dir;
for(int i = 0; i < k; i++) {
stk = new StringTokenizer(br.readLine());
idx = stoi(stk.nextToken()) - 1; // 돌릴 톱니바퀴의 순서
dir = stoi(stk.nextToken()); // 방향, 1 : 시계방향 / -1 : 반시계 방향
turnGear(idx,dir, false, false);
}
for(Deque<Integer> oneGear : gear) {
if(oneGear.peekFirst() == 1)
result++;
}
System.out.println(result);
br.close();
}
private static void turnGear(int idx, int dir, boolean leftTurned, boolean rightTurned) {
Stack<Integer> temp = new Stack<>();
int tempL;
boolean leftDiff = false, rightDiff = false;
// 현재 기어의 오른쪽을 확인한다.
if(idx != n - 1 && !rightTurned) {
temp.add(gear.get(idx).pollFirst());
temp.add(gear.get(idx).pollFirst());
tempL = gear.get(idx + 1).pollLast();
if(gear.get(idx).peekFirst() != gear.get(idx + 1).peekLast())
rightDiff = true;
gear.get(idx).addFirst(temp.pop());
gear.get(idx).addFirst(temp.pop());
gear.get(idx + 1).addLast(tempL);
}
// 현재 기어의 왼쪽을 확인한다.
if(idx != 0 && !leftTurned) {
temp.add(gear.get(idx - 1).pollFirst());
temp.add(gear.get(idx - 1).pollFirst());
tempL = gear.get(idx).pollLast();
if(gear.get(idx - 1).peekFirst() != gear.get(idx).peekLast())
leftDiff = true;
gear.get(idx - 1).addFirst(temp.pop());
gear.get(idx - 1).addFirst(temp.pop());
gear.get(idx).addLast(tempL);
}
turnOneGear(idx, dir);
// 왼쪽 기어가 돌아가면
if(leftDiff) {
turnGear(idx - 1, reverse(dir), false, true);
}
// 오른쪽 기어가 돌아가면
if(rightDiff) {
turnGear(idx + 1, reverse(dir), true, false);
}
}
// 방향을 바꾼다.
private static int reverse(int dir) {
if(dir == 1)
return -1;
else
return 1;
}
// 기어 하나를 돌린다.
private static void turnOneGear(int idx, int dir) {
int temp;
if(dir == 1) { // 시계 방향
temp = gear.get(idx).pollLast();
gear.get(idx).addFirst(temp);
}
else { // 반시계 방향
temp = gear.get(idx).pollFirst();
gear.get(idx).addLast(temp);
}
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}