코딩문제 풀이

14891번 톱니바퀴

student513 2020. 1. 21. 15:07
 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴가 1번, 그 오른쪽은 2번, 그 오른쪽은 3번, 가장 오른쪽 톱니바퀴는 4번이다. 이때, 톱니바퀴를 총 K번 회전시키려고 한다. 톱니바퀴의 회전은 한 칸을 기준으로 한다. 회전은 시계 방향과 반시계 방향이 있고, 아래 그림과 같이 회전한다. 톱니바퀴를 회전시키려

www.acmicpc.net

deque를 이용하면 쉽게 접근할 수 있는 문제

 

두 가지 사항을 고려했다.

 

1. 특정 톱니바퀴에 대한 시계방향 회전 function, 반시계방향 회전 function

2. 각 톱니바퀴와 맞물린 톱니바퀴의 상태

 

2번 고려사항에 대한 고민은

 

i번째 톱니바퀴가 회전했을 때 그 인접, 더 나아가서는 전체 톱니바퀴가 동시에 변화된 상태를 어떻게 체크할 것인가?

 

뭔가 반복문으로 체크하기에는 왼쪽으로는 인덱스가 감소해야하고 오른쪽으로는 증가해야해서 

 

도저히 아이디어가 떠오르지 않았다.

 

결국 조건문으로 노가다성 코드를 작성했다. 

 

톱니바퀴가 4개밖에 없어서 가능했지만 100개, 1000개 주어질 경우에는 대비하지 못했다.

 

Smart하지 못하군...

 

#include <iostream>
#include <vector>
#include <deque>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

deque<int> dq[4];
vector<pair<int, int>> vec;
bool state[4];
int K;
int score;

void print() {
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 8; j++) {
			cout << dq[i][j]<<" ";
		}
		cout << '\n';
	}
}
void r_func(int wheel) {
	int temp;
	temp = dq[wheel].back();
	dq[wheel].pop_back();
	dq[wheel].push_front(temp);
}
void l_func(int wheel) {
	//반시계방향
	int temp;
	temp = dq[wheel].front();
	dq[wheel].pop_front();
	dq[wheel].push_back(temp);
}

int main() {
	for (int i = 0; i < 4; i++) {
		string str;
		cin >> str;
		for (int j = 0; j < 8; j++) {
			if (str[j] == '0')
				dq[i].push_back(0);
			else
				dq[i].push_back(1);
		}
	}
	//print();
	cin >> K;
	vec.push_back(make_pair(-1, -1));
	for (int i = 0; i < K; i++) {
		int first, second;
		cin >> first >> second;
		vec.push_back(make_pair(first, second));
	}

	for (int i = 1; i <= K; i++) {
		memset(state, false, sizeof(state));
		if (dq[0][2] != dq[1][6]) state[0] = true;
		if (dq[1][2] != dq[2][6]) state[1] = true;
		if (dq[2][2] != dq[3][6]) state[2] = true;

		if (vec[i].second == 1) {//시계방향
			if (vec[i].first == 1) {//1번 톱니
				r_func(0);
				if (state[0]) {
					l_func(1);
					if (state[1]) {
						r_func(2);
						if (state[2]) {
							l_func(3);
						}
					}
				}
			}
			else if (vec[i].first == 2) {//2번 톱니
				r_func(1);
				if (state[0]) {
					l_func(0);
				}
				if (state[1]) {
					l_func(2);
					if (state[2]) {
						r_func(3);
					}
				}
			}
			else if (vec[i].first == 3) {//3번 톱니
				r_func(2);
				if (state[1]) {
					l_func(1);
					if (state[0]) {
						r_func(0);
					}
				}
				if (state[2]) {
					l_func(3);
				}
			}
			else {//4번 톱니
				r_func(3);
				if (state[2]) {
					l_func(2);
					if (state[1]) {
						r_func(1);
						if (state[0]) {
							l_func(0);
						}
					}
				}
			}
		}
		else {//반시계방향
			if (vec[i].first == 1) {//1번 톱니
				l_func(0);
				if (state[0]) {
					r_func(1);
					if (state[1]) {
						l_func(2);
						if (state[2]) {
							r_func(3);
						}
					}
				}
			}
			else if (vec[i].first == 2) {//2번 톱니
				l_func(1);
				if (state[0]) {
					r_func(0);
				}
				if (state[1]) {
					r_func(2);
					if (state[2]) {
						l_func(3);
					}
				}
			}
			else if (vec[i].first == 3) {//3번 톱니
				l_func(2);
				if (state[1]) {
					r_func(1);
					if (state[0]) {
						l_func(0);
					}
				}
				if (state[2]) {
					r_func(3);
				}
			}
			else {//4번 톱니
				l_func(3);
				if (state[2]) {
					r_func(2);
					if (state[1]) {
						l_func(1);
						if (state[0]) {
							r_func(0);
						}
					}
				}
			}
		}
	}

	if (dq[0][0]) score += 1;
	if (dq[1][0]) score += 2;
	if (dq[2][0]) score += 4;
	if (dq[3][0]) score += 8;

	cout << score;
	return 0;
}

'코딩문제 풀이' 카테고리의 다른 글

13908번 비밀번호  (0) 2020.02.04
17144번 미세먼지 안녕!  (0) 2020.01.30
14888번 연산자 끼워넣기  (0) 2020.01.17
14889번 스타트와 링크  (0) 2020.01.16
14503번 로봇 청소기  (0) 2020.01.15