baekjoon/Implementation
백준 14891번 : 톱니바퀴 [자바]
Meluu_
2025. 7. 24. 09:57
🧫 문제 분석
✔️ 출처
📖 문제


전체적인 로직이해는 잘 했는데
실시간 톱니가 회전된 상태에서 N, S를 비교하는게 아니라
회전하기전 상태에서 비교하는건데 이걸 캐치하지 못했다.
또한 변동idx값을 따로 저장하는데
-의 경우 8보다 커지면
+ 8을 해줘도 인덱스가 -로 Array Index Out Of Bounds Exceptions가 터졌다.
음수로 변동값을 주었을때 그 값이 배열의 크기를 넘어버리면 안된다.
따라서 해당 변동값 자체도 나눠버리면 된다.
🔅 문제 풀이
import java.io.*;
import java.util.*;
public class Main {
// 14891번 톱니바퀴
// 시계방향 -1
// 반시계방향 +1
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[][] arr = new char[4][8];
int[] dist = new int[4]; // 이동 값
for (int i = 0; i < 4; i++) {
arr[i] = br.readLine().toCharArray();
}
int K = Integer.parseInt(br.readLine());
for (int i = 0; i < K; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int idx = Integer.parseInt(st.nextToken()) - 1;
int dir = Integer.parseInt(st.nextToken()); // 돌아가는 변동 거리로 볼 수 있음
// 변동값 임시 저장
int[] tmp = new int[4];
// 주변 톱니 먼저 회전
// 왼쪽 파트
int leftDir = dir;
for (int j = idx-1; j >= 0; j--) {
int curLeftIdx = (6 + dist[j + 1] + 8) % 8;
int nextRightIdx = (2 + dist[j] + 8) % 8;
if (arr[j+1][curLeftIdx] != arr[j][nextRightIdx]) {
tmp[j] = leftDir;
leftDir *= -1;
} else {
break;
}
}
// 오른쪽 파트
int rightDir = dir;
for (int j = idx + 1; j < 4; j++) {
int curRightIdx = (2 + dist[j-1] + 8) % 8;
int nextLeftIdx = (6 + dist[j] + 8) % 8;
// 서로 다른 극이라면 회전
if (arr[j-1][curRightIdx] != arr[j][nextLeftIdx]) {
tmp[j] = rightDir;
rightDir *= -1;
} else {
break;
}
}
for (int j = 0; j < 4; j++) {
dist[j] += tmp[j];
dist[j] %= 8; // 변동값이 음수이면서 -8이하로 되는것을 방지
}
// 그 후 현재 톱니 회전
dist[idx] += (dir * - 1);
}
int sum = 0;
// 12시 정각은 0번 인덱스
for (int i = 0; i < 4; i++) {
int topIndex = (dist[i] + 8) % 8;
if (arr[i][topIndex] == '1') {
sum += 1 << i;
}
}
System.out.println(sum);
}
}
❗ 오답노트 / 필요한 지식
- 원의 인덱스를 구할 경우 음수를 조심하고 변동값이 클 때는 불확실하다면 더 쪼개서 나누자
- 문제를 더 꼼꼼히 읽고 알아낸 정보를 확실하게 적자