https://www.acmicpc.net/problem/14891
int[][] gears
gears[톱니바퀴 번호][톱니 번호]
: 해당 톱니바퀴의 톱니 상태회전시킬 톱니바퀴를 회전 시키기 전,
연쇄적으로 맞닿은 톱니바퀴들의 회전 여부 및 회전 방향 결정
1) [i]
번 톱니바퀴를 회전시키려는 경우
왼쪽 [i-1]
번 톱니바퀴의 오른쪽 [3]
번 톱니
vs [i]
번 톱니바퀴의 왼쪽 [7]
번 톱니
오른쪽 [i+1]
번 톱니바퀴의 왼쪽 [7]
번 톱니
vs [i]
번 톱니바퀴의 오른쪽 [3]
번 톱니
=> 각각 재귀호출
2) 2개의 톱니바퀴의 왼쪽 / 오른쪽 톱니의 극이 서로 다른 경우, 회전
각 톱니바퀴의 회전: 왼쪽 / 오른쪽으로 shift
1) 시계 방향 회전
2) 반시계 방향 회전
int[][] gears
: 각 톱니바퀴의 톱니 상태
Pair[] pairs
: 입력 회전 방법 순서
=> 회전 시킬 톱니바퀴 번호, 회전 방향
int[] directions
: 각 회전 명령에 따라, 각 톱니바퀴의 회전 방향 결정
boolean[] check
: 각 회전 명령에 따라, 각 톱니바퀴의 회전 방향을 결정할 때 톱니바퀴의 방문 여부 확인
1) 입력 회전 명령 1개에 대해, 각 톱니바퀴의 회전 방향 결정
2) 톱니바퀴 1개를 회전: 8
import java.io.*;
import java.util.StringTokenizer;
class Pair {
public int gearIdx; // 회전시킬 톱니바퀴 번호
public int direction; // 회전 방향
public Pair(int gearIdx, int direction) {
this.gearIdx = gearIdx;
this.direction = direction;
}
}
public class Main {
static int[][] gears; // 4개 톱니바퀴의 톱니 상태, [톱니바퀴 번호][톱니 번호]
static int k; // 회전 횟수
static Pair[] pairs; // 회전 방법 순서
static int[] directions; // 각 톱니바퀴의 회전 여부 및 방향 (1: 시계, -1: 반시계)
static boolean[] check;
static int sum; // k번 회전 후, 4개 톱니바퀴의 점수 합
static void solution() {
// 입력 회전 순서에 따라 회전 수행
for (int i = 0; i < k; i++) {
Pair current = pairs[i];
check = new boolean[5]; // [1] ~ [4] 사용
directions = new int[5];
check[current.gearIdx] = true;
directions[current.gearIdx] = current.direction;
setDirection(current.gearIdx);
for (int j = 1; j <= 4; j++) {
if (directions[j] == 1)
rotateClock(j);
else if (directions[j] == -1)
rotateCounterClock(j);
}
}
// 결과 톱니바퀴 점수 계산
for (int i = 1; i <= 4; i++) {
if (gears[i][1] == 1)
sum += (int)Math.pow(2, i - 1);
}
// if (gears[1][1] == 1) sum += 1;
// if (gears[2][1] == 1) sum += 2;
// if (gears[3][1] == 1) sum += 4;
// if (gears[4][1] == 1) sum += 8;
}
/* 인자로 받은 톱니바퀴의 왼쪽, 오른쪽 톱니바퀴의 회전 여부 및 방향 결정 */
static void setDirection(int gearIdx) {
int leftGearIdx = gearIdx - 1;
if (leftGearIdx >= 1 && !check[leftGearIdx]) {
check[leftGearIdx] = true;
// gearIdx 의 왼쪽 [7]번 톱니와 leftGearIdx 의 오른쪽 [3]번 톱니 비교
if (gears[gearIdx][7] != gears[leftGearIdx][3]) {
directions[leftGearIdx] = directions[gearIdx] * (-1);
setDirection(leftGearIdx);
}
}
int rightGearIdx = gearIdx + 1;
if (rightGearIdx <= 4 && !check[rightGearIdx]) {
check[rightGearIdx] = true;
// gearIdx 의 오른쪽 [3]번 톱니와 rightGearIdx 의 왼쪽 [7]번 톱니 비교
if (gears[gearIdx][3] != gears[rightGearIdx][7]) {
directions[rightGearIdx] = directions[gearIdx] * (-1);
setDirection(rightGearIdx);
}
}
}
/* 톱니바퀴 시계 방향 회전: 오른쪽으로 shift */
static void rotateClock(int gearIdx) {
int temp = gears[gearIdx][8];
for (int i = 8; i >= 2; i--)
gears[gearIdx][i] = gears[gearIdx][i - 1];
gears[gearIdx][1] = temp;
}
/* 톱니바퀴 반시계 방향 회전: 왼쪽으로 shift */
static void rotateCounterClock(int gearIdx) {
int temp = gears[gearIdx][1];
for (int i = 1; i <= 7; i++)
gears[gearIdx][i] = gears[gearIdx][i + 1];
gears[gearIdx][8] = temp;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
gears = new int[5][9]; // [1][1] ~ [4][8] 사용
for (int i = 1; i <= 4; i++) {
String str = br.readLine();
for (int j = 1; j <= 8; j++)
gears[i][j] = Character.getNumericValue(str.charAt(j - 1));
}
k = Integer.parseInt(br.readLine());
pairs = new Pair[k];
for (int i = 0; i < k; i++) {
st = new StringTokenizer(br.readLine());
int gearIdx = Integer.parseInt(st.nextToken());
int direction = Integer.parseInt(st.nextToken());
pairs[i] = new Pair(gearIdx, direction);
}
solution();
System.out.println(sum);
}
}