[DFS] 14891 톱니바퀴 C++

Seunghyeon·2023년 1월 22일

백준 문제 푼다.

목록 보기
6/21

코드


#include <bits/stdc++.h>

using namespace std;

vector<deque<int>> gear;

int k; // 회전 횟수
int t; // 극성 변수
int number[100]; // 톱니바퀴 번호
int dir[100]; // 1 : 시계 방향 -1 : 반시계 방향
int visited[4] = { 0, };
int sum = 0;

// A B C D 톱니가 있을 때
// A를 시계방향으로 돌렸을 때 
// A 과 B가 맞닿은 부분이 극이 반대라면 B는 반시계방향으로 돈다.
// A 과 B가 맞닿은 부분이 극이 같다면 돌지 않는다.

void dfs(int num, int dir)
{
	// 1번 기어가 아니면서 왼쪽 기어의 극이 다를 경우
	if (num != 0 && !visited[num - 1] && gear[num][6] != gear[num - 1][2])
	{
		visited[num - 1] = 1;
		dfs(num - 1, dir * -1);
	}

	// 4번 기어가 아니면서 오른쪽 기어의 극이 다를 경우
	if (num != 3 && !visited[num + 1] && gear[num][2] != gear[num + 1][6])
	{
		visited[num + 1] = 1;
		dfs(num + 1, dir * -1);
	}

	// 시계 방향
	if (dir == 1)
	{
		int temp = gear[num].back();
		gear[num].pop_back();
		gear[num].push_front(temp);
	}
	// 반시계 방향
	if (dir == -1)
	{
		int temp = gear[num].front();
		gear[num].pop_front();
		gear[num].push_back(temp);
	}
}

int main()
{
	for (int i = 0; i < 4; i++)
	{
		deque<int> temp;
		gear.push_back(temp);

		cin >> t;

		for (int j = 0; j < 8; j++)
		{
			gear[i].push_front(t % 10);
			t = t / 10;
		}
	}

	cin >> k;

	for (int i = 0; i < k; i++)
	{
		cin >> number[i] >> dir[i];
	}

	for (int i = 0; i < k; i++)
	{
		memset(visited, 0, sizeof(visited));
		visited[number[i] - 1] = 1;
		dfs(number[i] -1, dir[i]);
	}

	for (int i = 0; i < 4; i++)
	{
		if (gear[i][0] == 1)
			sum += (1 << i);
	}

	cout << sum;

	return 0;
}

풀이 방법


구현에 시뮬레이션 문제인데 DFS로 해결할 수 있을것 같아서 DFS로 해결해보았다.

1번 기어와 4번 기어는 각각 오른쪽 왼쪽에 기어가 없기 때문에 별도로 다루어 줘야 하고
나머지 기어는 옆의 기어와 맞닿은 극을 확인해주면 끝이다.

visited 배열로 중복으로 기어를 돌리는 문제를 해결해주고

  • 중요한것은 Deque를 사용하여 기어를 돌리기 편하도록 하였다는 것이다.

for문으로 하나하나 돌릴수는 있지만 당연히 느려질 것이고 코드 짜기도 귀찮고 불편하니까
기어를 Deque로 선언하여 앞에서, 뒤에서 빼고 넣기 쉽게 만들어준다.

그렇게 되면 매우 간단해진다.

그리고 마지막에 출력할 때 기어의 [0] 인덱스 마다 1, 2, 4, 8의 값을 부여하는데

이는 비트연산자로 값을 더해주면 간단하게 구현된다.

profile
그냥 합니다.

0개의 댓글