알고리즘 분류 : 구현, 시뮬레이션

 

이번 문제는 단순히 주어진 조건에 따라 구현을 해내면 되는 문제였다.

 

 

 

문제를 먼저 해석하자면 톱니바퀴가 아래와 같은 모양으로 4개가 주어진다. 순서대로 1,2,3,4 바퀴이다.

 

톱니바퀴 중 하나는 시계방향, 반시계 방향으로 돌릴 수 있다.

반시계 / 시계

이때, 양 옆의 톱니바퀴는 돌아가는 톱니바퀴와 같은 극성이라면 돌리지 않고,

다른 극성이라면 돌아가는 톱니바퀴와 반대 방향으로 돌아간다.

 

처음에 돌릴 바퀴가 주어지면 양옆의 바퀴가 돌아가거나 돌아가지 않고, 돌아간다면 양 옆의 바퀴가 또 돌아가거나 돌아가지 않고 ...  이런 식으로 연쇄적인 반응이 나타난다.

 

 

 

문제를 푼 방식은 우선 돌리기 직전 상황의 바퀴 정보를 저장해두는 것이다.

12시 방향의 톱니를 1이라고 하고 시계방향으로 번호를 매겨준다면

1번 바퀴의 3번과 2번 바퀴의 7번, 2번 바퀴의 3번과 3번 바퀴의 7번, 3번 바퀴의 3번과 4번 바퀴의 7번이 맞물린다.

따라서 돌리기 직전 bool three_wh[5], seven_wh(5]의 배열을 이용해서 각 톱니바퀴의 3번과 7번을 저장해두었다.

 

 

또한 연쇄반응을 이용했는데

1번에서 시작 -> 2번 -> 3번 -> 4번

2번에서 시작 -> 1번

                  -> 3번 -> 4번

3번에서 시작 -> 2번 -> 1번

                  -> 4번

4번에서 시작 -> 3번 -> 2번 -> 1번 

이런 식으로 움직이기 때문에 내 옆에서 돌기 시작한 바퀴의 번호와 그 방향을 알려주면 맞물린 곳을 비교한 후, 같으면 돌지 않고 다르면 반대 방향으로 돌았다.

만약 내가 처음으로 돌기 시작했다면 내 옆에서 돌기 시작한 바퀴는 0번으로 예외처리를 해두었다.

이 부분은 코드 주석을 보는 게 이해가 훨씬 빠르다!

//톱니바퀴 골드 5
#include<iostream>

using namespace std;

string wheel[5];
bool three_wh[5], seven_wh[5];

void one(int start, int turn);
void two(int start, int turn);
void three(int start, int turn);
void four(int start, int turn);

// 같으면 안움직이고 다르면 반대 방향으로
void wise(int turn, int w) {
	if (turn == 1) {
		int temp = wheel[w][7];
		for (int j = 7;j > 0;j--) {
			wheel[w][j] = wheel[w][j - 1];
		}
		wheel[w][0] = temp;
	}
	else {
		int temp = wheel[w][0];
		for (int j = 0;j < 7;j++) {
			wheel[w][j] = wheel[w][j + 1];
		}
		wheel[w][7] = temp;
	}
	
}

void one(int start, int turn) {
	//단독 시작
	if (!start) {
		two(1,turn); 

		wise(turn, 1);
	}
	else { //2번 시작
		if (three_wh[1] == seven_wh[2]) return;
		else wise(-turn, 1);
	}
	
}

void two(int start, int turn) {
	// 단독 시작
	if (!start) {
		one(2,turn);
		three(2,turn);

		wise(turn, 2);
	}
	
	if (start == 1) { // 1번 시작 -> 3번으로
		if (three_wh[1] == seven_wh[2]) return;

		three(2, -turn);

		wise(-turn, 2);
	}
	else if (start == 3) { // 3번 시작 -> 1번으로
		if (three_wh[2] == seven_wh[3]) return;

		one(2, -turn);

		wise(-turn, 2);
	}
}

void three(int start, int turn) {
	// 단독 시작
	if (!start) {
		two(3, turn);
		four(3, turn);

		wise(turn, 3);
	}

	if (start == 2) { // 2번 시작 -> 4번으로
		if (three_wh[2] == seven_wh[3]) return;

		four(3, -turn);

		wise(-turn, 3);
	}
	else if (start == 4) { // 4번 시작 -> 2번으로
		if (three_wh[3] == seven_wh[4]) return;

		two(3, -turn);

		wise(-turn, 3);
	}
}

void four(int start, int turn) {
	//단독 시작
	if (!start) {
		three(4, turn);

		wise(turn, 4);
	}
	else { //3번 시작
		if (three_wh[3] == seven_wh[4]) return;
		else wise(-turn, 4);
	}

}

int main() {
	
	for (int i = 1; i < 5;i++) {
		cin >> wheel[i]; // N극은 0, S극은 1
	}

	int K; cin >> K;
	int w, t, temp;
	

	for (int i = 0;i < K;i++) {
		for (int j = 1;j < 5;j++) {
			three_wh[j] = wheel[j][2] - 48;
			seven_wh[j] = wheel[j][6] - 48;
		}

		cin >> w >> t;
		switch (w) {
		case 1:
			one(0, t);
			break;
		case 2:
			two(0, t);
			break;
		case 3:
			three(0, t);
			break;
		case 4:
			four(0, t);
			break;
		}
	}

	cout << (wheel[1][0] - 48) * 1 + (wheel[2][0] - 48) * 2 + (wheel[3][0] - 48) * 4 + (wheel[4][0] - 48) * 8;

}

//2024KB, 0ms

 

 

'coding > baekjoon_codingstudy' 카테고리의 다른 글

19238 스타트택시  (0) 2022.10.02
13460 구슬 탈출2  (0) 2022.10.02
18239 편안한 수열 만들기 (골드 3)  (0) 2021.08.19
11657 타임머신 (골드 4)  (0) 2021.08.15
4386 별자리 만들기 (골드 4)  (0) 2021.08.15

+ Recent posts