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






난이도: solved.ac 골드 5
알고리즘 분류
구현, 시뮬레이션
접근 방법
한 톱니바퀴의 양 옆 톱니바퀴는 반대 방향으로 돈다.
예를 들어 3번 톱니바퀴가 시계 방향으로 돈다면, 2번 톱니바퀴와 4번 톱니바퀴는 반시계 방향으로 돈다.
그리고 톱니바퀴의 톱니는 8개로 이루어져 있으며, 앞 톱니바퀴의 3번째 톱니(3시 방향)와 현재 톱니바퀴의 7번째 톱니(9시 방향)가 서로 맞닿아있다.
맞닿아있는 톱니의 극이 달라야 톱니바퀴가 돌아가며, 극이 같으면 톱니바퀴가 돌아가지 않는다.
구현
톱니바퀴가 가진 각 톱니의 번호(N극, S극)는 arr에 저장하였고 rotate라는 배열에 각 톱니바퀴의 회전 방향을 저장하였다.
rotate가 1이면 시계 방향, -1이면 반시계 방향, 0이면 회전하지 않음을 의미한다.
입력으로 들어오는 톱니바퀴의 번호는 num이라는 변수에 저장했고, num번 톱니바퀴를 시작으로 각 톱니와 맞닿은 톱니의 번호를 비교한다.
번호가 서로 다르면(극이 서로 다르면) 기준이 되는 톱니바퀴가 회전하는 방향과 반대 방향으로 회전하도록 rotate에 저장하였다.
이때 회전 방향은 tmp_turn이라는 변수에 -1을 곱하는 식으로 계산했다.
각 톱니의 번호 비교가 끝나면 rotate에 저장된 각 톱니의 회전 방향을 토대로 arr를 수정해주었다.
코드
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> int arr[4][8]; int rotate[4]; // 각 톱니바퀴가 회전할 방향을 저장 int main() { int K, i, j, temp; for (i = 0; i < 4; i++) { for (j = 0; j < 8; j++) { scanf("%1d", &arr[i][j]); } } scanf("%d", &K); int num, turn; // num; 톱니바퀴 번호, turn: 도는 방향 while (K) { scanf("%d %d", &num, &turn); num--; rotate[num] = turn; int tmp_turn = turn; for (i = num - 1; i >= 0; i--) { tmp_turn *= -1; // 톱니바퀴는 한 칸 옆 톱니바퀴와 도는 방향이 반대이므로 if (arr[i][2] != arr[i + 1][6]) rotate[i] = tmp_turn; else break; } tmp_turn = turn; for (i = num + 1; i < 4; i++) { tmp_turn *= -1; if (arr[i][6] != arr[i - 1][2]) rotate[i] = tmp_turn; else break; } for (i = 0; i < 4; i++) { // 시계 방향 if (rotate[i] == 1) { temp = arr[i][7]; for (j = 7; j > 0; j--) arr[i][j] = arr[i][j - 1]; arr[i][0] = temp; } else if (rotate[i] == -1) { // 반시계 방향 temp = arr[i][0]; for (j = 0; j < 7; j++) arr[i][j] = arr[i][j + 1]; arr[i][7] = temp; } } // 각 톱니의 회전 방향 0으로 초기화 memset(rotate, 0, sizeof(rotate)); K--; } int ans = 0; if (arr[0][0]) ans += 1; if (arr[1][0]) ans += 2; if (arr[2][0]) ans += 4; if (arr[3][0]) ans += 8; printf("%d", ans); return 0; }