티스토리 뷰
문제 - (https://www.acmicpc.net/problem/14891)
시뮬레이션 문제... 솔직히 시간 좀 많이 잡아먹는다
실버 1 수준의 문제인데도 푸는데 1시간 정도 걸렸다
구현 문제는 특히 헷갈리는 부분 때문에 실수가 잦아 조심해야 한다
우선 꼭 짚고 넘어가야 할 것들만 언급하고 주의할 점과 내가 실수한 것을 쓰고 마치겠다
👀짚고 넘어가야 할 부분1 - 톱니바퀴 회전시키기
static String clockRotate(String state, int dir) {
if (dir == 1) { // 시계 방향
return state.charAt(state.length() - 1) + state.substring(0, state.length() - 1);
} else { // 반시계 방향
return state.substring(1) + state.charAt(0);
}
}
다른 사람 풀이를 보니까 배열로 만들어서 푸셨던데.. 난 그냥 문자열 떼서 붙이는 방법 사용했다.
시계방 향일 경우, 문자열의 마지막 글자를 떼어내서 앞에 붙임
반시계 방향일 경우, 문자열 첫 번째 글자를 떼어내서 마지막에 붙임
👀짚고 넘어가야 할 부분2 - 재귀 구현하기
톱니바퀴 하나를 이동시키게 되면 그 톱니바퀴와 연결된 왼쪽, 오른쪽 톱니바퀴에도 영향이 미친다. 영향이 미친 톱니바퀴가 회전하게 되면 그 옆의 톱니바퀴에도 영향을 미친다. 이런 연쇄적인 현상 때문에 재귀로 구현해야겠다는 생각을 했다. (하지만 톱니가 4개밖에 없으니 굳이 재귀는 아니어도 상관없을 듯)
내가 구현한 재귀 구조는 회전해야 하는 톱니바퀴들 중 가장 끝에 있는 것부터 회전시키는 방식이다.
void rotate(int idx, int dir, boolean l, boolean rr)에서 boolean값의 의미는,
만약에 왼쪽 톱니바퀴가 움직이게 된다면 왼쪽 톱니바퀴로 재귀 진입을 하게 되는데, 그 상태에서는 계속해서 왼쪽에만 영향을 끼치므로 오른쪽 톱니바퀴에는 관여하지 않게 하기 위한 장치이다.
📌주의할 점
- 처음 움직일 톱니바퀴는 왼쪽 톱니바퀴와 오른쪽 톱니바퀴 모두 영향을 끼친다.
- 톱니바퀴 1과 톱니바퀴 4는 각각 왼쪽 톱니바퀴, 오른쪽 톱니바퀴가 없다.
- 12방향이 1일 때 톱니바퀴별로 점수가 부여되므로 score배열에 1,2,4,8을 넣어 점수 합계를 쉽게 했다.
😅실수
- 재귀 내부에서 계산 작업이 이루어진다면 진입할 때 계산을 하는 게 맞을지에 대해 고민은 꼭 해봐야 한다.
아래 코드의 /**/ 주석에 설명이 적혀있음
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 실버1 - 1시간
public class Gear {
static String[] gears = new String[5];
static int[] score = {0, 1, 2, 4, 8};
static int k;
static void rotate(int idx, int dir, boolean l, boolean r) {
// 현재 기어의 왼쪽, 오른쪽 기어 idx
int leftIdx = idx - 1;
int rightIdx = idx + 1;
// 현재 기어와 왼쪽 기어 비교
if (l && leftIdx >= 1 && gears[idx].charAt(6) != gears[leftIdx].charAt(2)) {
// 다르면 왼쪽 기어 반대방향으로 회전
rotate(leftIdx, -dir, true, false);
/* 왼쪽 톱니바퀴에 진입한 후에 그 톱니바퀴가 현재 톱니바퀴가 되어 회전하는 작업을 "ㄱ"줄에서
* 진행하므로 여기서 회전작업을 해버리면 중복 회전시키게 된다. */
// gears[leftIdx] = clockRotate(gears[leftIdx], -dir);
}
if (r && rightIdx <= 4 && gears[idx].charAt(2) != gears[rightIdx].charAt(6)) {
// 다르면 오른쪽 기어 반대방향으로 회전
rotate(rightIdx, -dir, false, true);
// gears[rightIdx] = clockRotate(gears[rightIdx], -dir);
}
// 현재 기어 회전시키기
/* ㄱ */gears[idx] = clockRotate(gears[idx], dir);
}
static String clockRotate(String state, int dir) {
if (dir == 1) { // 시계 방향
return state.charAt(state.length() - 1) + state.substring(0, state.length() - 1);
} else { // 반시계 방향
return state.substring(1) + state.charAt(0);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
gears[1] = br.readLine();
gears[2] = br.readLine();
gears[3] = br.readLine();
gears[4] = br.readLine();
k = Integer.parseInt(br.readLine());
for (int i = 0; i < k; i++) {
st = new StringTokenizer(br.readLine());
rotate(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), true, true);
}
int answer = 0;
for (int i = 1; i <= 4; i++) {
if (gears[i].charAt(0) == '1') {
// S극이면 점수가 있음
answer += score[i];
}
}
System.out.println(answer);
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 14503번 / Java / 로봇 청소기 - 구현, 시뮬레이션 (0) | 2020.06.24 |
---|---|
[백준] 14502번 / Java / 연구소 - DFS, 완전탐색 (0) | 2020.06.24 |
[백준] 14888번 / Java / 연산자 끼워넣기 - 완전탐색, 백트래킹 (0) | 2020.06.23 |
[백준] 15684번 / Java / 사다리 조작 - DFS, 시뮬레이션, 완전탐색 풀이 (0) | 2020.06.08 |
[백준] 16234번 / Java / 인구 이동 (0) | 2020.06.07 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- withCredentials
- 구명보트
- 자바
- 코딩테스트 연습
- 아기상어
- 우선순위큐
- 재귀
- java
- 16234
- 코테
- 구현
- 완전탐색
- 14891
- 코딩테스트
- Greedy
- 브라우저 요청
- BOJ
- 프로그래머스
- header
- 톱니바퀴
- 그리디
- 인구이동
- 배열순회
- 사다리 조작
- 백준
- 드래곤 커브
- Access-Control-Allow-Origin
- 시뮬레이션
- dfs
- 큰 수 만들기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함