Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

코린이 탈출기

[백준 14891] 톱니바퀴 본문

문제 풀이/DFS

[백준 14891] 톱니바퀴

명란파스타 2020. 7. 22. 20:41

문제 바로가기

 

14891번: 톱니바퀴

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

www.acmicpc.net

 

문제 이해만 잘 하면 금방 풀 수 있다.

톱니바퀴 네 개가 일렬로 놓여져있고, 왼쪽 톱니바퀴의 2번째와 오른쪽 톱니바퀴의 6번째가 맞물려있는데, 회전하는 톱니바퀴 기준으로 맞물린 부분의 극이 서로 다르면 맞물린 다른 톱니바퀴도 도는 방식으로 작동한다.

 

따라서, 이를 DFS 백트래킹 방식으로 구현하였다.

rotate(int num, int dir)가 재귀적으로 호출되며, num은 톱니바퀴 번호, dir은 톱니바퀴가 회전하는 방향 정보를 담고있다.

회전하는 톱니바퀴 양 옆의 톱니바퀴가 회전가능한 조건(극이 달라야 함)을 가진다면 rotate 함수를 호출한다.

 

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;

int chain[4][8];
int check[3];
int visited[4];
int n;

void rotate_right(int num) {
	int tmp = chain[num][7];
	for (int i = 6; i >= 0; i--)
	{
		chain[num][i + 1] = chain[num][i];
	}
	chain[num][0] = tmp;
}

void rotate_left(int num)
{
	int tmp = chain[num][0];
	for (int i = 1; i <= 7; i++)
	{
		chain[num][i - 1] = chain[num][i];
	}
	chain[num][7] = tmp;
}

bool isIn(int num)
{
	if (num >= 0 && num < 4)
		return true;
	return false;

}
void rotate(int num, int dir)//dir == -1 : left 
{
	int converse_dir;
	visited[num] = 1;

	if (dir == -1) {
		rotate_left(num);
		converse_dir = 1;
	}
	else {
		rotate_right(num);
		converse_dir = -1;
	}
		

	if (!visited[num-1] && isIn(num - 1) && check[num - 1])
	{
		rotate(num - 1, converse_dir);
	}
		

	if (!visited[num+1] && isIn(num + 1) && check[num]) {
		rotate(num + 1, converse_dir);
	}
		

}

int main()
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			scanf("%1d", &chain[i][j]);
		}
	}

	cin >> n;
	
	for (int i = 0; i < n; i++)
	{
		int num, dir;
		cin >> num >> dir;
		for (int j = 1; j < 4; j++)
		{
			if (chain[j][6] != chain[j - 1][2])// 극이 다름
			{
				check[j - 1] = 1;
			}
		}
		rotate(num-1, dir);
		memset(visited, 0, sizeof(visited));
		memset(check, 0, sizeof(check));
	}

	int sum = 0;

	for (int i = 0; i < 4; i++)
	{
		if (chain[i][0] == 1)//S극
			sum += pow(2, i);
	}

	cout << sum << endl;

	return 0;
}

'문제 풀이 > DFS' 카테고리의 다른 글

[백준 15683] 감시  (0) 2020.07.27
[백준 14889] 스타트와 링크  (0) 2020.07.25
[백준 14888] 연산자 끼워넣기  (0) 2020.07.25
[백준 19236] 청소년 상어  (0) 2020.07.22