난이도 ★☆☆
문제출처
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;
}
'알고리즘 > 삼성' 카테고리의 다른 글
삼성 코딩테스트 기출_(백준)테트로미노 (0) | 2019.10.04 |
---|---|
삼성 코딩테스트 기출_(백준)로봇 청소기 (1) | 2019.10.02 |
삼성 코딩테스트 기출_(백준)주사위 굴리기 (0) | 2019.09.25 |
삼성 코딩테스트 기출_(백준)감시 (0) | 2019.09.25 |
삼성 코딩테스트 기출_(백준)퇴사 (1) | 2019.09.16 |
댓글