mojo's Blog

[백준 14891] 톱니바퀴 본문

백준/simulation

[백준 14891] 톱니바퀴

_mojo_ 2021. 8. 30. 21:23

문제 링크 => https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net


삼성 역량 테스트 문제로 시뮬레이션 문제이다.

 

톱니바퀴 4개를 2차원 배열 Wheel[4][8] 으로 설정하고 접근하였다. ( i 번의 x번 톱니바퀴 => Wheel[i - 1][x - 1] )

 

일단 빠르게 구현할 수 있는 것으로 회전에 대한 부분이다.

 

시계 방향일 경우 1 => 2, 2 => 3, ... , 8 => 1 이런식으로 이동할 것이므로 다음과 같은 코드가 된다.

 

int tmp = Wheel[wheelNum][7];
for (int i = 7; i > 0; i--) {
	Wheel[wheelNum][i] = Wheel[wheelNum][i - 1];
}
Wheel[wheelNum][0] = tmp;

 

반시계 방향일 경우 8 => 7 , 7 => 6 , ... , 1 => 8 이런식으로 이동할 것이므로 다음과 같은 코드가 된다.

 

int tmp = Wheel[wheelNum][0];
for (int i = 0; i < 7; i++) {
	Wheel[wheelNum][i] = Wheel[wheelNum][i + 1];
}
Wheel[wheelNum][7] = tmp;

 

마지막으로 톱니바퀴의 회전에 대한 구현 부분이다.

 

1. 1 번의 톱니바퀴가 회전하는 경우를 살펴보면 다음과 같다.

(0) 1 번의 톱니바퀴 회전

(1) 1 번의 2번 톱니바퀴와 2 번의 6번 톱니바퀴가 다른 경우 => 2 번의 톱니바퀴 회전 ( 같은 경우 break ) 

(2) 2 번의 2번 톱니바퀴와 3 번의 6번 톱니바퀴가 다른 경우 => 3 번의 톱니바퀴 회전 ( 같은 경우 break )

(3) 3 번의 2번 톱니바퀴와 4 번의 6번 톱니바퀴가 다른 경우 => 4 번의 톱니바퀴 회전 ( 같은 경우 break )

 

이때, 4 번의 톱니바퀴 또한 1 번의 톱니바퀴처럼 양 끝에 배치하므로 똑같은 매커니즘으로 구현하면 된다.

 

2. 2 번의 톱니바퀴가 회전하는 경우를 살펴보면 다음과 같다.

(0) 2 번의 톱니바퀴 회전 ( (0) => (1) 인 경우와 (0) => (2) 인 경우를 동시에 보도록 함 )

(1) 1 번의 2번 톱니바퀴와 2 번의 6번 톱니바퀴가 다른 경우 => 1 번의 톱니바퀴 회전 ( 같은 경우 break )

(2) 2 번의 2번 톱니바퀴와 3 번의 6번 톱니바퀴가 다른 경우 => 3 번의 톱니바퀴 회전 ( 같은 경우 break )

(3) 3 번의 2번 톱니바퀴와 4 번의 6번 톱니바퀴가 다른 경우 => 4 번의 톱니바퀴 회전 ( 같은 경우 break )

 

이때, 2 번의 톱니바퀴 또한 3 번의 톱니바퀴처럼 중앙에 배치하므로 똑같은 매커니즘으로 구현하면 된다.

 

풀이 Code

 

#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define INF 1000000000
#define endl '\n'
#define ll long long

using namespace std;

int Wheel[4][8];
int K;
queue<pair<int, int>> commandQ;

void input() {

	for (int i = 0; i < 4; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < 8; j++) {
			Wheel[i][j] = s[j] - '0';
		}
	}

	cin >> K;
	for (int i = 0; i < K; i++) {
		int wheelNum, direction;
		cin >> wheelNum >> direction;
		commandQ.push({ wheelNum - 1,direction });
	}

}

int reverseDirection(int direction) {
	if (direction == 1) return -1;
	return 1;
}

void rotate(int wheelNum, int direction) {
	
	if (direction == 1) { // 시계 방향
		int tmp = Wheel[wheelNum][7];
		for (int i = 7; i > 0; i--) {
			Wheel[wheelNum][i] = Wheel[wheelNum][i - 1];
		}
		Wheel[wheelNum][0] = tmp;
	}
	else { // 반시계 방향
		int tmp = Wheel[wheelNum][0];
		for (int i = 0; i < 7; i++) {
			Wheel[wheelNum][i] = Wheel[wheelNum][i + 1];
		}
		Wheel[wheelNum][7] = tmp;
	}

}

void wheelRotate(int wheelNum, int direction) {

	if (wheelNum == 0) {
		if (Wheel[0][2] != Wheel[1][6]) {
			if (Wheel[1][2] != Wheel[2][6]) {
				if (Wheel[2][2] != Wheel[3][6]) {
					rotate(3, reverseDirection(direction));
				}
				rotate(2, direction);
			}
			rotate(1, reverseDirection(direction));
		}
		rotate(0, direction);
	}
	else if (wheelNum == 1) {
		if (Wheel[0][2] != Wheel[1][6]) {
			rotate(0, reverseDirection(direction));
		}
		if (Wheel[1][2] != Wheel[2][6]) {
			if (Wheel[2][2] != Wheel[3][6]) {
				rotate(3, direction);
			}
			rotate(2, reverseDirection(direction));
		}
		rotate(1, direction);
	}
	else if (wheelNum == 2) {
		if (Wheel[2][2] != Wheel[3][6]) {
			rotate(3, reverseDirection(direction));
		}
		if (Wheel[1][2] != Wheel[2][6]) {
			if (Wheel[0][2] != Wheel[1][6]) {
				rotate(0, direction);
			}
			rotate(1, reverseDirection(direction));
		}
		rotate(2, direction);
	}
	else {
		if (Wheel[2][2] != Wheel[3][6]) {
			if (Wheel[1][2] != Wheel[2][6]) {
				if (Wheel[0][2] != Wheel[1][6]) {
					rotate(0, reverseDirection(direction));
				}
				rotate(1, direction);
			}
			rotate(2, reverseDirection(direction));
		}
		rotate(3, direction);
	}

}

int getScore(int index) {
	if (Wheel[index][0] == 0) return 0;
	return pow(2, index);
}

void solve() {

	int result = 0;
	while (!commandQ.empty()) {
		int wheelNum = commandQ.front().first;
		int direction = commandQ.front().second;
		commandQ.pop();

		wheelRotate(wheelNum, direction);
	}

	for (int i = 0; i < 4; i++) {
		result += getScore(i);
	}
	cout << result << endl;

}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	input();
	solve();

	return 0;
}

 

'백준 > simulation' 카테고리의 다른 글

[백준 19236] 청소년 상어  (0) 2022.03.31
[백준 15685] 드래곤 커브  (0) 2021.12.29
[백준 15683] 감시  (0) 2021.08.31
[백준 14890] 경사로  (0) 2021.08.29
[백준 14499] 주사위 굴리기  (0) 2021.08.29
Comments