톱니바퀴
문제풀이
- 나의 구현력을 테스트하는 문제이다.
- 우선 톱니가 어떻게 돌아가는지 파악하는 것이 중요하다.
- 같은 극을 띠고 있는 톱니가 맞물린다면 돌아가지 않는다.
- 다른 극을 띠고 있는 톱니가 맞물린다면 돌아간다.
- 나는 아래의 순서로 했다.
- 현재 선택된 톱니바퀴를 기준점으로 잡고 좌 톱니, 우 톱니의 값을 인덱스 형태로 저장한다.
- 현재 선택된 톱니바퀴를 기준으로 왼쪽의 톱니바퀴를 돌린다.
- 현재 선택된 톱니바퀴를 기준으로 오른쪽의 톱니바퀴를 돌린다.
- 톱니를 K번 돌리고나서 12시 방향에 있는 톱니의 극을 확인해서 score 값에 누적한다.
- 구현력 혹은 시뮬레이션이라 부르는 문제들에 대해서 최대한 머릿속에 그려서 올바른 사고로 정확한 답을 도출해내는 연습이 필요함을 느낄 수 있다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static InputStreamReader isr;
static BufferedReader br;
static OutputStreamWriter osw;
static BufferedWriter bw;
static StringTokenizer st;
public static void main(String[] args) throws IOException {
isr = new InputStreamReader(System.in);
br = new BufferedReader(isr);
osw = new OutputStreamWriter(System.out);
bw = new BufferedWriter(osw);
String line = null;
String[]values = new String[5];
int[][]element = new int[5][2];
for(int i = 0; i < 4; i++) {
line = br.readLine();
values[i+1] = line;
element[i+1][0] = 6;
element[i+1][1] = 2;
}
int K = Integer.parseInt(br.readLine());
for(int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int number = Integer.parseInt(st.nextToken());
int direction = Integer.parseInt(st.nextToken());
int[]wheelInfo = element[number];
/** 톱니는 8개다 **/
boolean isRight = (direction == 1)? true : false;
/** 회전하는 톱니의 왼쪽 부분과 오른쪽 부분 **/
/** 미리 값을 가지고 있는다. **/
int localLeftToothed = wheelInfo[0];
int localRightToothed = wheelInfo[1];
/** 톱니 위치는 변경 **/
if(isRight) {
/** 시계 **/
wheelInfo[0] -= 1;
wheelInfo[1] -= 1;
}else {
/** 반시계 **/
wheelInfo[0] += 1;
wheelInfo[1] += 1;
}
settingWheel(wheelInfo);
element[number] = wheelInfo;
int[][]standard = element;
/** 왼쪽 : 왼쪽 톱니를 돌린다 **/
for(int left = number - 1; left >= 1; left--) {
int[]leftWheelInfo = standard[left];
/** 값을 확인 **/
if(values[left].charAt(leftWheelInfo[1]) == values[left+1].charAt(localLeftToothed)) {
break;
}else {
if(isRight) {
localLeftToothed = leftWheelInfo[0];
/** 반시계방향 **/
leftWheelInfo[0] += 1;
leftWheelInfo[1] += 1;
isRight = false;
}else {
localLeftToothed = leftWheelInfo[0];
/** 시계방향 **/
leftWheelInfo[0] -= 1;
leftWheelInfo[1] -= 1;
isRight = true;
}
settingWheel(leftWheelInfo);
element[left] = leftWheelInfo;
}
}
/** 현재 톱니가 돌아가는 방향을 다시 초기화해준다. 이전에 왼쪽 톱니 옮기면서 섞여있기 떄문에 **/
isRight = (direction == 1)? true : false;
/** 오른쪽 : 오른쪽 톱니 돌린다 **/
for(int right = number + 1; right < 5; right++) {
int[]rightWheelInfo = standard[right];
if(values[right].charAt(rightWheelInfo[0]) == values[right-1].charAt(localRightToothed)) {
break;
}else {
if(isRight) {
localRightToothed = rightWheelInfo[1];
/** 반시계방향 **/
rightWheelInfo[0] += 1;
rightWheelInfo[1] += 1;
isRight = false;
}else {
localRightToothed = rightWheelInfo[1];
/** 시계방향 **/
rightWheelInfo[0] -= 1;
rightWheelInfo[1] -= 1;
isRight = true;
}
settingWheel(rightWheelInfo);
element[right] = rightWheelInfo;
}
}
}
int score = 0;
/** score 획득하기 **/
for(int n = 0; n < 4; n++) {
int[]wheelInfo = element[n+1];
/** 12시에 가리키는 값 **/
int time = wheelInfo[0] + 2;
time %= 8;
if(values[n+1].charAt(time) == '0') {
continue;
}
if(n == 0) {
score += 1;
} else if(n == 1) {
score += 2;
} else if(n == 2) {
score += 4;
} else {
score += 8;
}
}
bw.write(score + "\n");
bw.flush();
bw.close();
br.close();
}
/**
* 휠 조정 <p>
* @param wheelInfo
*/
private static void settingWheel(int[]wheelInfo) {
if(wheelInfo[0] == 8) {
wheelInfo[0] = 0;
}
if(wheelInfo[0] == -1) {
wheelInfo[0] = 7;
}
if(wheelInfo[1] == 8) {
wheelInfo[1] = 0;
}
if(wheelInfo[1] == -1) {
wheelInfo[1] = 7;
}
}
}
'Problem Solving & Algorithm > BOJ ' 카테고리의 다른 글
20190407 1373번 : 2진수 8진수 (0) | 2019.04.07 |
---|---|
20190406 1652번 : 누울 자리를 찾아라 (0) | 2019.04.06 |
20190401 1197번 : 최소 스패닝 트리 (0) | 2019.04.02 |
20190331 14500번 : 테트로미노 (0) | 2019.03.31 |
20190309 1922번 : 네트워크 연결 (0) | 2019.03.09 |