본문 바로가기
  • 책과 글
알고리즘/삼성

삼성 코딩테스트 기출_(백준)톱니바퀴

by twfnm67 2019. 10. 1.

난이도 ★☆☆

 

문제출처

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

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴가 1번, 그 오른쪽은 2번, 그 오른쪽은 3번, 가장 오른쪽 톱니바퀴는 4번이다. 이때, 톱니바퀴를 총 K번 회전시키려고 한다. 톱니바퀴의 회전은 한 칸을 기준으로 한다. 회전은 시계 방향과 반시계 방향이 있고, 아래 그림과 같이 회전한다. 톱니바퀴를 회전시키려

www.acmicpc.net

 

포인트

1. check(int i, int dir)

현재 상태에서, 4개의 톱니바퀴 중 회전 할 톱니바퀴를 모두 사전에 체크하는 함수이다. 재귀를 돌며, i번째 톱니바퀴가 dir방향으로 돌게 될 것이라는 정보를 mustMove[i]=dir의 형태로 저장해준다.

 

2. mustMove[i]

i번째 톱니바퀴가 어느 방향으로 회전할지 저장되어 있는 배열이다.

(예_mustMove[3]=-1은 세 번째 톱니바퀴가 반시계방향으로 회전한다는 의미)

 

3. move(int i, int dir)

main에서 mustMove[i]의 방향을 확인하고, 0이 아닌 경우 실제로 회전을 시키기 위해서 move(i, dir)을 호출한다.

 

4. 주의할 점

입력받는 톱니들은 공백으로 구분되어 있지 않기 때문에 cin으로 받아줄 수 없다. 따라서 scanf("%1d", &gear[i][j])를 사용하였다.

 

정답코드

#include <iostream>
using namespace std;

const int CLOCKWISE = 1;
const int COUNTER_CLOCKWISE = -1;

int gear[5][8]; // gear[i][j]는 i번째 톱니바퀴의 j번째 톱니 정보
int mustMove[5]; // mustMove[i]의 값이 0이면 i번째 톱니바퀴는 회전X, -1이면 반시계회전, 1이면 시계회전
int visit[5];//재귀를 돌 때 방문 여부를 확인하기 위한 배열
int K;//회전 횟수

void check(int i, int dir) {//i번째 톱니바퀴가 dir방향으로 회전하게 되는지 확인하는 함수
	visit[i] = 1;
	mustMove[i] = dir;
	
	int nextDir = 0;
	if (dir == CLOCKWISE)nextDir = COUNTER_CLOCKWISE;
	else if (dir == COUNTER_CLOCKWISE)nextDir = CLOCKWISE;

	if (i - 1 >= 1 && !visit[i-1]&& mustMove[i] != 0 && gear[i - 1][2] != gear[i][6]) {
		check(i - 1, nextDir);
	}
	if (i + 1 <= 4 && !visit[i+1] && mustMove[i] != 0 && gear[i + 1][6] != gear[i][2]) {
		check(i + 1, nextDir);
	}
}

void move(int i, int dir) {//i번째 톱니를 dir방향으로 회전시키는 함수
	int temp = 0;
	switch (dir) {
	case CLOCKWISE:
		temp = gear[i][0];
		gear[i][0] = gear[i][7];
		gear[i][7] = gear[i][6];
		gear[i][6] = gear[i][5];
		gear[i][5] = gear[i][4];
		gear[i][4] = gear[i][3];
		gear[i][3] = gear[i][2];
		gear[i][2] = gear[i][1];
		gear[i][1] = temp;
		break;
	case COUNTER_CLOCKWISE:
		temp = gear[i][0];
		gear[i][0] = gear[i][1];
		gear[i][1] = gear[i][2];
		gear[i][2] = gear[i][3];
		gear[i][3] = gear[i][4];
		gear[i][4] = gear[i][5];
		gear[i][5] = gear[i][6];
		gear[i][6] = gear[i][7];
		gear[i][7] = temp;
		break;
	}
}
int main() {
	for (int i = 1; i <= 4; i++) {
		for (int j = 0; j < 8; j++) {
			scanf("%1d", &gear[i][j]);
		}
	}
	cin >> K;
	while (K--) {
		for (int i = 1; i <= 4; i++) {
			mustMove[i] = 0;
			visit[i] = 0;
		}//초기화

		int i, dir;
		cin >> i >> dir;
		check(i, dir);
		for (int i = 1; i <= 4; i++) {
			if (mustMove[i] != 0) move(i, mustMove[i]);
		}
	}

	int score = 0;
	if (gear[1][0] == 1)score += 1;
	if (gear[2][0] == 1)score += 2;
	if (gear[3][0] == 1)score += 4;
	if (gear[4][0] == 1)score += 8;

	cout << score << '\n';

	return 0;
}

댓글