거의 알고리즘 일기장

백준 14891번 _ 톱니바퀴 본문

알고리즘 문제풀이

백준 14891번 _ 톱니바퀴

건우권 2020. 4. 30. 15:39

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

 

14891번: 톱니바퀴

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

www.acmicpc.net

풀이방법

이 문제도 그냥 시뮬레이션 문제다. 그러므로 주의사항을 보고 꼼꼼히만 코딩을 완성하기만 하면 어렵지않다.

 

한가지만 주의하자

1. 이미 돌렸던 기어는 다시 돌리면 안된다.

  재귀문을 짤때 이 부분을 넣어주지 않으면 재귀문이 끝나지 않을 수 있다.


전체코드

#include<iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;
int Gears[4][8];
vector<pair<int, int>> orders;

void Input()
{
	string value;
	for (int i = 0; i < 4; i++)
	{
		cin >> value;
		for (int j = 0; j < 8; j++)
		{
			Gears[i][j] = value[j] - '0';
		}
	}

	int n;
	cin >> n;
	int gearNum, dir;
	for (int i = 0; i < n; i++)
	{
		cin >> gearNum >> dir;
		orders.push_back({ gearNum, dir });
	}
}

void CCW(int gearNum)
{
	queue<int> que;
	int gearIdx = gearNum - 1;

	//que push
	for (int j = 0; j < 8; j++)
		que.push(Gears[gearIdx][j]);

	//회전
	que.push(que.front());
	que.pop();

	//회전한 값 넣기
	for (int j = 0; j < 8; j++)
	{
		Gears[gearIdx][j] = que.front();
		que.pop();
	}
}

void CW(int gearNum)
{
	//CCW를 7번돌리면 CW
	for (int i = 0; i < 7; i++)
		CCW(gearNum);
}

bool inRange(int n)
{
	if (n > 0 && n <= 4)
		return true;
	return false;
}

int changeDir(int dir)
{
	if (dir == -1)
		return 1;
	else
		return -1;
}

int d[] = { -1, 1 };
//before -1 왼쪽, 0 양쪽, 1 오른쪽
void gearMove(int gearNum, int dir, int before)
{
	//일단 양옆으로 보낸다
	for (int i = 0; i < 2; i++)
	{
		int ngearNum = gearNum + d[i];
		int ndir = changeDir(dir);
		//범위를 넘어서면 안됨
		if (inRange(ngearNum) == false)
			continue;

		//현재 기어와 옆의 기어가 극이 달라야함
		//왼쪽
		if (i == 0 && (before == 0 || before == -1)) 
		{
			if (Gears[gearNum - 1][6] == Gears[ngearNum - 1][2])
				continue;
			//여기까지 통과했다면 ㄱㄱ
			gearMove(ngearNum, ndir, -1);
		}
		//오른쪽
		if(i == 1 && (before == 0 || before == 1))
		{
			if (Gears[gearNum - 1][2] == Gears[ngearNum - 1][6])
				continue;
			//여기까지 통과했다면 ㄱㄱ
			gearMove(ngearNum, ndir, 1);
		}
	}

	//바꾸기
	if (dir == 1)
		CW(gearNum);
	else
		CCW(gearNum);
}

void solve()
{
	int answer = 0;
	for (auto& order : orders)
	{
		int gearNum = order.first;
		int dir = order.second;
		gearMove(gearNum, dir, 0);
	}

	answer += (Gears[0][0] + Gears[1][0] * 2 + Gears[2][0] * 4 + Gears[3][0] * 8);
	cout << answer;
}

int main()
{
	Input();
	solve();

	return 0;
}

후기

구현만 한다면, 테스트케이스만 맞춘다면 통과하는 문제다. 

하지만 구현은 정말 귀찮다.. 

반응형

'알고리즘 문제풀이' 카테고리의 다른 글

codeforces_ 158B_ Taxi  (0) 2020.05.02
백준 15683번_ 감시  (0) 2020.05.01
백준 14890번_경사로  (0) 2020.04.30
백준 14889번 _ 스타트와 링크  (0) 2020.04.29
알고스팟_ 와일드 카드_ 종만북_DP  (0) 2020.04.29
Comments