https://www.acmicpc.net/problem/15662
15662번: 톱니바퀴 (2)
총 8개의 톱니를 가지고 있는 톱니바퀴 T개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴가 1번, 그 오른쪽은 2번, ..., 가장 오른쪽 톱니바퀴는 T번이다. 아래 그림은 T가 4인 경우이다. 이때, 톱니바퀴를 총 K번 회전시키려고 한다. 톱니바퀴의 회전은 한 칸을 기준으로 한다. 회전은 시계 방향과 반시계 방향이 있고, 아래 그림과 같이 회전한다
www.acmicpc.net
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#include<stdio.h>
#include<iostream>
#include<string.h>
#define TSIZE 1001
using namespace std;
int gearRot[TSIZE];
char gearState[TSIZE][8];
int T,K,ret;
void init() {
scanf("%d", &T);
for (int i = 1; i <= T; i++) {
scanf("%s", gearState[i]);
}
}
void rightClock(int num) {
int end = gearState[num][7];
for (int i = 6; i >= 0; i--) {
gearState[num][i+1] = gearState[num][i];
}
gearState[num][0] = end;
}
void leftClock(int num) {
int start = gearState[num][0];
for (int i = 1; i < 8; i++) {
gearState[num][i - 1] = gearState[num][i];
}
gearState[num][7] = start;
}
void play() {
scanf("%d", &K);
for (int i = 0; i < K; i++) {
int gearNum; int dir;
scanf("%d %d", &gearNum, &dir);
memset(gearRot, 0, sizeof(gearRot));
gearRot[gearNum] = dir;
for (int L = gearNum; L <= T-1; L++) {
if (gearState[L][2] == gearState[L + 1][6]) gearRot[L + 1] = 0;
else {
gearRot[L + 1]= gearRot[L]* -1;
}
}
for (int R = gearNum; R >= 1; R--) {
if (gearState[R][6] == gearState[R - 1][2])gearRot[R - 1] = 0;
else {
gearRot[R-1] = gearRot[R] * -1;
}
}
for (int j = 1; j <= T; j++) {
if (gearRot[j] == -1) { leftClock(j); }
else if (gearRot[j] == 1) { rightClock(j); }
}
}
for (int i = 1; i <= T; i++) {
if (gearState[i][0] == '1') ret++;
}
}
int main(void) {
init();
play();
cout << ret << endl;
return 0;
}
|
톱니 바퀴는 구현할게 많긴하지만 이것하나만 기억하시면 쉽게 풀립니다.
우선 구현할것을 적습니다.
1. 시계방향으로 톱니 돌릴 것 (오른쪽으로 이동하기에 right 라고 붙였습니다)

2. 반시계 방향으로 톱니 돌릴 것 (왼쪽으로 이동하기에 left 라고 붙였습니다)

3. 입력으로 주어지는 위치에서 왼쪽 으로 확인해서 어느방향으로 돌릴지 정하는것

4. 입력으로 주어지는 위치에서 오른쪽으로 확인해서 어느방향으로 돌릴지 정하는것

5. 방향 정해진것을 토대로 돌리기

이렇게 5가지만 잘 구현하면됩니다.
1,2,5번은 말할것도 없는 그냥 배열 돌리기라 설명은 생략하고
3,4 번만 간단히 설명하겠습니다. 그리고 이 문제를 간혹 돌리면서 하시는 분 있는데 그렇게 되면
2번위치의 톱니와 6번위치 톱니를 또 따로 저장해야해서 그냥 돌릴 방향을 저장만하고 나중에 한번에
돌리는것을 추천드립니다. 정말 그래야 정신 건강에 좋더라구요.
무튼

그림을 보고 2은 L 이므로 2와 6 번 방을 검사해야하고
R은 6 과 2를 검사해야합니다.
현재 인덱스 기준으로 생각하시면됩니다.
이때 2 ==6 이면 같은면 움직이지 않기때문에 0 을
다르면 -1 일때는 1 을 1일때는 -1 을 해야하므로 그 위치에방향의 *-1 을 해주면 됩니다.
저희들은 이미 시계방향과 반시계방향으로 돌리는 함수를 만들어 놨기때문에
1-T까지 포문을 돌리면서 돌려주면 됩니다. 정말 쉬워지지 않나요?
이래서 설계가 중요한것 같습니다.
이해 안되시는 부분은 남겨주시면 최선을 다해서 이해시켜드리겠습니다. 오늘은 여기까지이고
오늘하루도 즐거운 알고하세요.

'알고리즘 모음집 > 알고리즘 (Algorithm)' 카테고리의 다른 글
백준 4577 소코반 (0) | 2019.09.30 |
---|---|
백준 1260 DFS와 BFS (0) | 2019.09.29 |
백준 1194 달이 차오른다, 가자. (0) | 2019.09.25 |
백준 1600 말이 되고픈 원숭이 (0) | 2019.09.23 |
백준 16637 괄호 추가하기 (0) | 2019.09.22 |
댓글