문제가 기니까 잘 읽고 이해해야한다.
풀이
같은 극이 맞닿은 톱니는 돌아가지 않고
다른 극이 맞닿은 톱니는 반대 방향으로 돈다.
이 두개의 조건이 핵심이다.
해당 기어의 번호 앞뒤로 반복문을 통해 기어를 돌리는 전형적인 시뮬레이션 문제다.
시뮬레이션 문제는 노하우는 있겠지만 구현을 시켜내면 되는 문제기 때문에 시간이 많이 걸리는 편이다.
n 번 톱니의 3번째 톱니와 n+1 번 톱니의 7번 톱니의 극이 같은지를 확인해서 돌려야한다.
static void moveGear(int gear_number, int direct) {
int lastPole6 = (int) gear[gear_number].get(6);
int lastPole2 = (int) gear[gear_number].get(2);
spinGear(gear_number, direct);
int direct_tmp = direct;
for(int j = gear_number - 1; j >= 0 ; j--) {
int tmp = (int) gear[j].get(6);
//다른극 반대 방향
if(lastPole6 != (int)gear[j].get(2)) {
direct_tmp *= -1;
spinGear(j, direct_tmp);
}
//같은 극 끝냄.
else {
break;
}
lastPole6 = tmp;
}
direct_tmp = direct;
for(int j = gear_number + 1 ; j < 4 ; j++ ) {
int tmp = (int) gear[j].get(2);
//다른극 반대방향
if(lastPole2 != (int)gear[j].get(6)) {
direct_tmp *= -1;
spinGear(j, direct_tmp);
}
//같은극 끝냄
else
break;
lastPole2 = tmp;
}
}
해당 기어의 앞뒤 기어들을 반복문으로 돌아가며 변하기 전의 기어 극을 저장해 놓고 다른극인지 같은극인지를 판단해서 방향을 돌려준다.
앞서 돌린 기어의 방향과 반대이므로 앞서 돌린 기어의 방향을 저장해 주어야한다.
톱니가 돌아가는 방식
시계방향의 경우
8번째 톱니가 12시방향에 오게된다. -> 리스트 제일 뒤의 톱니가 0번째 순서로 온다.
반시계방향의 경우
12시 방향의 톱니가 8번째 톱니가 된다. -> 0번째 톱니가 리스트 제일 뒤로 간다.
static void spinGear(int idx, int direct) {
if(direct == 1) {
int last = (int) gear[idx].remove(gear[idx].size() - 1);
gear[idx].add(0, last);
}
else {
int front = (int) gear[idx].remove(0);
gear[idx].add(gear[idx].size(), front);
}
}
<전체코드>
import java.io.*;
import java.util.*;
public class Main {
static StringBuilder sb = new StringBuilder();
static List[] gear;
public static void main(String[] args) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
gear = new List[4];
for(int i = 0 ; i < 4 ; i++) {
gear[i] = new ArrayList<Integer>();
}
for(int i = 0 ; i < 4 ; i++) {
String[] pole = bufferedReader.readLine().split("");
for(int j = 0 ; j < 8 ; j++) {
gear[i].add(Integer.parseInt(pole[j]));
}
}
int K = Integer.parseInt(bufferedReader.readLine());
for(int i = 0 ; i < K ; i++) {
StringTokenizer st = new StringTokenizer(bufferedReader.readLine());
int gearNumber = Integer.parseInt(st.nextToken());
int direct = Integer.parseInt(st.nextToken());
moveGear(gearNumber -1, direct);
}
System.out.println(checkingPoint());
}
static int checkingPoint() {
int point = 0;
for(int i = 0 ; i < 4 ; i++) {
if((int)gear[i].get(0) == 1) {
point += Math.pow(2, i);
}
}
return point;
}
static void moveGear(int gear_number, int direct) {
int lastPole6 = (int) gear[gear_number].get(6);
int lastPole2 = (int) gear[gear_number].get(2);
spinGear(gear_number, direct);
int direct_tmp = direct;
for(int j = gear_number - 1; j >= 0 ; j--) {
int tmp = (int) gear[j].get(6);
//다른극 반대 방향
if(lastPole6 != (int)gear[j].get(2)) {
direct_tmp *= -1;
spinGear(j, direct_tmp);
}
else {
break;
}
lastPole6 = tmp;
}
direct_tmp = direct;
for(int j = gear_number + 1 ; j < 4 ; j++ ) {
int tmp = (int) gear[j].get(2);
if(lastPole2 != (int)gear[j].get(6)) {
direct_tmp *= -1;
spinGear(j, direct_tmp);
}
else
break;
lastPole2 = tmp;
}
}
static void spinGear(int idx, int direct) {
if(direct == 1) {
int last = (int) gear[idx].remove(gear[idx].size() - 1);
gear[idx].add(0, last);
}
else {
int front = (int) gear[idx].remove(0);
gear[idx].add(gear[idx].size(), front);
}
}
}
'알고리즘 공부 > 구현 , 시뮬레이션' 카테고리의 다른 글
[프로그래머스] 자물쇠와 열쇠 (0) | 2021.05.20 |
---|---|
백준 16434 (드래곤 앤 던전) - 이분탐색 (0) | 2021.04.29 |
백준 12764 (싸지방에 간 준하) - 정렬, 우선순위큐 (0) | 2021.04.29 |
백준 15997 (승부예측) (0) | 2021.04.28 |
백준 20926 (얼음 미로)**- 다익스트라알고리즘 (0) | 2021.04.26 |