다희의 코딩 성장일기
[백준] 15662. 톱니바퀴 (2) (자바 JAVA) 본문
[ 문제 ] [백준] 15662. 톱니바퀴 (2) (자바 JAVA)
문제 링크 : https://www.acmicpc.net/problem/15662
# 접근 방법 및 풀이
- 톱니바퀴를 topni[][] 2차원 배열에 입력받는다.
- 톱니바퀴끼리 서로 맞물린 곳의 극이 서로 달라 회전이 가능한지 체크하는 함수 check()
- 회전시키는 함수 rotation()
- 톱니바퀴 하나를 해당 방향(시계 or 반시계)으로 돌리는 함수 turn() 으로 3가지 함수를 구분해서 구현했다.
- 먼저, check()함수는 boolean check[] 배열을 만들어 각 맞물린 톱니바퀴끼리 서로 다른지 확인해서 다르면 true를 해준다.
- 이때 check[] 배열의 크기는 톱니바퀴 갯수 T-1이다.
-
1-2 2-3 3-4 T F T - 예를들어 T = 4 이면, 위와 같이 1번 2번 톱니바퀴 상태, 2번 3번 / 3번 4번 만 체크해주면 된다.
- 톱니바퀴는 길이가 8이고, 톱니바퀴를 배열로 표시하면 다음과 같다. Topni[4][8]
-
톱니 0 1 2 3 4 5 6 7 1번 0 1 1 1 0 0 1 0 2번 0 1 1 0 0 1 0 1 3번 1 1 1 0 0 0 0 1 4번 1 1 1 0 0 1 0 1 - 따라서 check[]배열은 맞물려 있는 2번째와 6번째 idx를 비교하면 된다.
- rotation() 함수는 먼저 돌려야 하는 해당 바퀴를 돌리고, 해당 바퀴 기준 왼쪽과 오른쪽을 나눠 순서대로 톱니바퀴를 회전시킨다.
-
1 2 3 4 5 6 - 예를들어, 3번 톱니바퀴를 회전시킨다면 3번을 먼저 회전시키고, 3번의 오른쪽인 4, 5, 6을 순서대로 회전시키고, 왼쪽인 2, 1을 순서대로 회전시킨다.
- 순서대로 회전시키는 이유는 5번,6번 톱니의 맞물린 곳이 N극과 S극으로 서로 달라 회전이 가능하다고 해도, 4번 톱니가 돌아야지만 5번 6번도 회전 가능하기 때문이다.
- turn() 함수는 d =1일 경우, 시계방향 d = -1일 경우 반시계방향으로 돌린다.
- 그리고 위의 과정을 K번 반복하면 된다.
- 자세한건 코드참조
# 주의할 점
- 처음에 문제를 잘못 봐서 K번씩 돌리는 건 줄 알고 잘못 풀었다..한번 돌리는건데..
- 로직 설계 빨리 했다고 해서 성급히 풀지말 것.
- 구현일 수록 변수를 잘 못 썻다거나, +1을 빼먹었다거나 > 등호를 잘못 썼다거나 그런 사소한 것에서 오류나니까 꼭 잘 확인하자!
JAVA 코드
package Silver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class bj15662_톱니바퀴_2 {
static int T, topni[][];
static boolean check[];
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
T = Integer.parseInt(in.readLine());
topni = new int[T][8];
for (int i = 0; i < T; i++) {
String s = in.readLine();
for (int j = 0; j < 8; j++) {
topni[i][j] = s.charAt(j) - '0';
}
}
int K = Integer.parseInt(in.readLine());
for (int i = 0; i < K; i++) {
st = new StringTokenizer(in.readLine());
int num = Integer.parseInt(st.nextToken())-1;
int d = Integer.parseInt(st.nextToken());
check = new boolean[T-1];
check();
rotation(num, d);
}
int ans = 0;
for (int i = 0; i < T; i++) {
ans += topni[i][0];
}
System.out.println(ans);
}
private static void rotation(int num, int d) {
turn(num, d);
if(T > 1) {
boolean turn[] = new boolean[T];
turn[num] = true;
//왼쪽
int leftdir = d*-1;
for (int i = num-1; i >= 0; i--) {
if(check[i] && turn[i+1]) {
turn[i] = true;
turn(i, leftdir);
leftdir *= -1;
}
}
//오른쪽
int rightdir = d*-1;
for (int i = num+1; i < T; i++) {
if(check[i-1] && turn[i-1]) {
turn[i] = true;
turn(i, rightdir);
rightdir *= -1;
}
}
}
}
private static void turn(int num, int d) {
if(d == 1) {
int tmp = topni[num][7];
for (int i = 7; i > 0; i--) {
topni[num][i] = topni[num][i-1];
}
topni[num][0] = tmp;
}else {
int tmp = topni[num][0];
for (int i = 0; i < 7; i++) {
topni[num][i] = topni[num][i+1];
}
topni[num][7] = tmp;
}
}
private static void check() {
for (int i = 0; i < T-1; i++) {
if(topni[i][2] != topni[i+1][6])
check[i] = true;
}
}
}
REVIEW
구현은 진짜 다시 생각해도.. 변수 하나 어디서 이상하게 잘못 쓰면 삽질을 너무 많이 한다...
더 확실하게 실수하지 않고 푸는 연습이 중요하다.
'Algorithm > 백준 BOJ' 카테고리의 다른 글
[백준] 5247. 불 (자바 JAVA) (0) | 2021.09.04 |
---|---|
[백준] 5567. 결혼식 (자바 JAVA) (0) | 2021.09.03 |
[백준] 2493. 탑 (자바 JAVA) (0) | 2021.08.22 |
[백준] 2583. 영역 구하기 (자바 JAVA) (0) | 2021.08.21 |
[백준] 1726. 로봇 (자바 JAVA) (0) | 2021.08.19 |
Comments