[백준/BOJ] 백준 14891번 : 톱니바퀴

2020. 8. 7. 18:26알고리즘 문제풀이

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

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴

www.acmicpc.net

input_number-1(0~3) 번 톱니바퀴를 turn_kind(-1:반시계 방향, 1:시계 방향)로 회전시키고 그 영향으로 돌아갈 수 있는 톱니바퀴들도 돌린다. 최종 톱니바퀴들의 모습을 통해 점수를 구한다

 

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

//톱니바퀴의 상태 저장
vector<string> wheel;

//left_right(-1:왼쪽으로 맞닿은 톱니바퀴 돌리기 진행중 1:오른쪽방향으로 맞닿은 톱니바퀴 돌리기 진행중, 0:해당 부분만 돌림)
//number번 톱니바퀴를 turn_kind방향으로 돌린다
void turnWheel(int number, int turn_kind, int left_right)
{
	//왼쪽으로 톱니바퀴 돌리기가 진행중 이므로 왼쪽에 맞닿은 톱니바퀴를 돌릴 수 있다면 돌린다
	if (left_right == -1)
	{
		if (number - 1 >= 0 && wheel[number - 1][2] != wheel[number][6])
			turnWheel(number - 1, turn_kind*(-1), -1);
	}

	//오른쪽으로 톱니바퀴 돌리기가 진행중 이므로 오른쪽에 맞닿은 톱니바퀴를 돌릴 수 있다면 돌린다
	else if (left_right == 1)
	{
		if (number + 1 < 4 && wheel[number][2] != wheel[number + 1][6])
			turnWheel(number + 1, turn_kind*(-1), 1);
	}

	//시계 반대 방향으로 톱니바퀴를 돌린다
	if (turn_kind == -1)
	{
		wheel[number] = wheel[number] + wheel[number][0];
		wheel[number] = wheel[number].substr(1);
	}

	//시계 방향으로 톱니바퀴를 돌린다
	else if (turn_kind == 1)
	{
		wheel[number] = wheel[number][7] + wheel[number];
		wheel[number] = wheel[number].substr(0, 8);
	}
}

//number번 톱니바퀴를 turn_kind(-1:시계반대 방향, 1:시계방향)으로 돌릴때 그 영향으로 돌아가는 톱니 바퀴들을 돌린다
void Solve(int number, int turn_kind)
{
	//number번 톱니바퀴를 기준으로 왼쪽으로 맞닿아 있는 톱니 바퀴를 돌린다(범위를 넘어가지 않고, 맞닿은 부분의 극이 다를때)
	if (number - 1 >= 0 && wheel[number - 1][2] != wheel[number][6])
		turnWheel(number - 1, turn_kind*(-1), -1);

	//number번 톱니바퀴를 기준으로 오른쪽으로 맞닿아 있는 톱니 바퀴를 돌린다(범위를 넘어가지 않고, 맞닿은 부분의 극이 다를때)
	if (number + 1 < 4 && wheel[number][2] != wheel[number + 1][6])
		turnWheel(number + 1, turn_kind*(-1), 1);

	//number번 톱니 바퀴를 돌린다
	turnWheel(number, turn_kind, 0);
}

int getScore()
{
	int ret = 0;

	//0~3번 톱니바퀴들의 점수 합을 구한다
	for (int i = 0; i < 4; i++)
	{
		if (wheel[i][0] == '1')
		{
			if (i == 0)
				ret += 1;

			else if (i == 1)
				ret += 2;

			else if (i == 2)
				ret += 4;

			else if (i == 3)
				ret += 8;
		}
	}

	return ret;
}

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

	string temp;
	int input_number, turn_kind;
	int k;

	//0~3번 톱니바퀴의 상태를 저장한다
	for (int i = 0; i < 4; i++)
	{
		cin >> temp;
		wheel.push_back(temp);
	}

	cin >> k;

	for (int i = 0; i < k; i++)
	{
		cin >> input_number >> turn_kind;

		//input_number-1(0~3)번 톱니 바퀴를 turn_kind(-1:반시계 방향, 1:시계 방향)로 회전시키고 그 영향으로 돌아갈 수 있는 톱니바퀴들도 돌린다
		Solve(input_number - 1, turn_kind);
	}

	//현재 톱니바퀴 상태에 따른 점수를 출력한다
	cout << getScore();

	return 0;
}