출처: https://www.acmicpc.net/problem/14891
Input
10101111
01111101
11001110
00000010
2
3 -1
1 1
Output
7
총 K번 회전시킨 이후 4개의 톱니바퀴 점수 합을 출력합니다.
- 1번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 1점
- 2번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 2점
- 3번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 4점
- 4번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 8점
[3]번 바퀴를 반시계방향으로 회전시킨다.
[4]번 바퀴는 N-S극 규칙으로 시계방향으로 한 번 회전한다.
* 3번 바퀴가 회전하기 전의 극의 정보로 인접한 바퀴의 회전 여부 결정
[2]번 바퀴는 S-S극으로 동일하기 때문에 변화가 없으며,
[1]번 바퀴에는 변화가 없다.
[1]번 바퀴를 시계방향으로 회전시킨다.
[2]번 바퀴는 S-N 규칙으로 인해 반시계 방향으로 회전한다.
[3]번 바퀴는 S-N 규칙으로 인해 시계방향으로 회전한다.
[4]번 바퀴는 N-N으로 같기 때문에 변화가 없다.
결과는 아래와 같습니다.
각 톱니바퀴의 12시 방향 점수를 구하면
▶ 1 + 2 + 4 = 7
* 톱니바퀴는 회전하기 시작한 지점에서 양옆으로만 회전시킨다.
톱니바퀴의 회전이 연쇄반응으로 되돌아 오지는 않는다.
[구현] 각 톱니바퀴의 톱니는 List로 구현
- 인접한 톱니바퀴의 맞닿은 극의 톱니는 2번째 6번째 요소입니다.
- 회전이 끝난 후, 12시 방향의 톱니는 첫번째 원소 값으로 정의하였습니다.
[시계 방향]
[반시계 방향]
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Machine machine = new Machine();
// 4개의 톱니바퀴에 대한 정보를 입력받는다.
for(int i=0; i<4; i++) {
String str = sc.next();
Gear gear = new Gear();
for(int j=0; j<str.length(); j++) {
int teeth = Integer.parseInt(str.substring(j, j+1));
gear.saw.add(teeth);
}
machine.gears.add(gear);
}
int rotateCnt = Integer.parseInt(sc.next());
// 회전하기
while(rotateCnt-- > 0) {
// 회전 톱니바퀴 번호 (리스트는 시작인덱스가 '0'이므로 입력받은 것에서-1을 해줘야 한다.)
int idx = Integer.parseInt(sc.next()) - 1;
// 회전 방향(시계 or 반시계 방향)
int direction = Integer.parseInt(sc.next());
machine.run(idx,direction);
}
int answer = 0;
for(int i=0; i<4; i++) {
Gear gear = machine.gears.get(i);
int target = gear.saw.get(0);
if(target == 0) continue;
// 2의 i승 형태를 이용
answer += Math.pow(2, i);
}
System.out.println(answer);
}
}
class Machine{
// 시계 & 반시계 방향
static final int FORWARD = 1;
static final int RERVERSE = -1;
List<Gear> gears;
public Machine() {
gears = new ArrayList<>();
}
public void run(int idx, int direction) {
Gear gear = gears.get(idx);
leftChain(idx, direction);
rightChain(idx, direction);
gear.rotate(direction);
}
private void leftChain(int idx, int direction) {
// 왼쪽에 영향을 미칠 톱니바퀴가 없으면(제일 왼쪽 톱니바퀴라면) stop
if(idx <= 0) return;
// 맞닿은 극을 비교한다.
// 극이 같다면 더 이상의 영향은 없다.
if(gears.get(idx).saw.get(6) == gears.get(idx-1).saw.get(2)) return;
// 극이 다르다면 현재 톱니바퀴에 대한 진행방향에 따른 처리를 해줘야 한다.
else {
// 현재 바퀴가 시계방향이면 왼쪽 바퀴는 반시계 방향이다.
if(direction == FORWARD) {
leftChain(idx-1, RERVERSE);
// 왼쪽 바퀴도 회전하기 전에 그 다음 왼쪽 바퀴에 영향을 주는지 처리한 뒤에 회전을 한다.
gears.get(idx-1).rotate(RERVERSE);
}
// 현재 바퀴가 반시계방향이면 왼쪽 바퀴는 시계 방향이다.
else if(direction == RERVERSE) {
leftChain(idx-1, FORWARD);
// 왼쪽 바퀴도 회전하기 전에 그 다음 왼쪽 바퀴에 영향을 주는지 처리한 뒤에 회전을 한다.
gears.get(idx-1).rotate(FORWARD);
}
}
}
private void rightChain(int idx, int direction) {
// 오른쪽에 영향을 미칠 톱니바퀴가 없으면(제일 오른쪽 톱니바퀴라면) stop
if(idx >= gears.size()-1) return;
// 맞닿은 극을 비교한다.
// 극이 같다면 더 이상의 영향은 없다.
if(gears.get(idx).saw.get(2) == gears.get(idx+1).saw.get(6)) return;
// 극이 다르다면 현재 톱니바퀴에 대한 진행방향에 따른 처리를 해줘야 한다.
else {
// 현재 바퀴가 시계방향이면 오른쪽 바퀴는 반시계 방향이다.
if(direction == FORWARD) {
rightChain(idx+1, RERVERSE);
// 오른쪽 바퀴도 회전하기 전에 그 다음 오른쪽 바퀴에 영향을 주는지 처리한 뒤에 회전을 한다.
gears.get(idx+1).rotate(RERVERSE);
}
// 현재 바퀴가 반시계방향이면 오른쪽 바퀴는 시계 방향이다.
else if(direction == RERVERSE) {
rightChain(idx+1, FORWARD);
// 오른쪽 바퀴도 회전하기 전에 그 다음 오른쪽 바퀴에 영향을 주는지 처리한 뒤에 회전을 한다.
gears.get(idx+1).rotate(FORWARD);
}
}
}
}
class Gear{
// 시계 & 반시계 방향
static final int FORWARD = 1;
static final int RERVERSE = -1;
List<Integer> saw;
public Gear() {
saw = new ArrayList<>();
}
public void rotate(int direction) {
// 시계 방향 회전인 경우
if(direction == FORWARD) {
// 제일 뒤에 있는 원소가 제일 앞으로 와서 12시 방향의 자리가 된다.
// 나머지 원소는 자동적으로 밀려난다.
saw.add(0, saw.remove(saw.size()-1));
}
// 반시계 방향 회전인 경우
else if(direction == RERVERSE) {
// 제일 앞에 있던 원소를 제일 뒤로 보낸다.
saw.add(saw.remove(0));
}
}
}
'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글
[BOJ] 백준 9251 LCS (0) | 2021.02.21 |
---|---|
[BOJ] 백준 5582 공통 부분 문자열 (Java) (0) | 2021.02.21 |
[BOJ] 백준 14890 경사로 (0) | 2021.02.21 |
[BOJ] 백준 14889 스타트와 링크 (0) | 2021.02.21 |
[BOJ] 백준 14888 연산자 끼워넣기 (0) | 2021.02.21 |
댓글