알고리즘

백준 14891번 톱니바퀴 C++

영춘권의달인 2022. 1. 6. 12:29

출처 : https://www.acmicpc.net/problem/14891

 

톱니바퀴의 각 정보를 벡터로 저장하고, 왼쪽으로 회전한다면 첫번째 원소를 erase하고 맨 뒤에 다시 넣고, 오른쪽으로 회전한다면 마지막 원소를 pop하고 insert하는 방식으로 작동하는 Rotate 함수를 만들었다.

 

그리고 Solve 함수에서 맞닿아있는 극이 다르다면 재귀적으로 함수를 실행하도록 하였다.

 

rotDir을 회전 방향, dir을 진행 방향으로 설정하여 왼쪽으로 진행하는 것과 오른쪽으로 진행하는 것을 따로 시뮬레이션 하였다. 그리고 한쪽으로 진행했다면 처음 돌린 톱니바퀴는 돌아가있는 상태이기 때문에 반대쪽으로 한번 회전시킨 뒤 다른쪽으로 진행하였다.

 

#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

using namespace std;
typedef long long ll;

vector<vector<int>> wheel(5);

void Rotate(int num, int rotDir) {
	if (rotDir == -1) {
		int tmp = wheel[num][0];
		wheel[num].erase(wheel[num].begin());
		wheel[num].push_back(tmp);
	}
	else {
		int tmp = wheel[num][7];
		wheel[num].pop_back();
		wheel[num].insert(wheel[num].begin(), tmp);
	}
}

void Solve(int num, int rotDir, int dir) {
	if (num <= 0 || num > 4) return;
	if (dir == -1) {
		int lastLeft = wheel[num][6];
		Rotate(num, rotDir);
		if (num == 1) {
			return;
		}
		if (wheel[num - 1][2] != lastLeft) {
			Solve(num - 1, -rotDir, dir);
		}
	}
	else {
		int lastRight = wheel[num][2];
		Rotate(num, rotDir);
		if (num == 4) {
			return;
		}
		if (wheel[num + 1][6] != lastRight) {
			Solve(num + 1, -rotDir, dir);
		}
	}
}

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

	string str;
	for (int i = 1; i <= 4; i++) {
		cin >> str;
		for (int j = 0; j < 8; j++) {
			wheel[i].push_back(str[j] - '0');
		}
	}
	int k;
	cin >> k;
	while (k--) {
		int num, rotDir;
		cin >> num >> rotDir;
		Solve(num, rotDir, -1);
		Rotate(num, -rotDir);
		Solve(num, rotDir, 1);
	}
	int ans = 0;
	int score = 1;
	for (int i = 1; i <= 4; i++) {
		if (wheel[i][0] == 1) {
			ans += score;
		}
		score *= 2;
	}
	cout << ans;
};