BOJ

[백준] 14891번 톱니바퀴 - C++

구현, 시뮬레이션, deque

Posted by dongjune on November 11, 2020

문제

14891 톱니바퀴

풀이

톱니바퀴는 12시 방향이 0번 index로 시작해서 시계방향 순서로 index를 갖는다.
나는 톱니바퀴의 회전 수행을 쉽게 하기 위해 톱니바퀴의 상태를 deque에 저장했다. 톱니바퀴의 2번 인덱스오른쪽 톱니, 6번 인덱스는 왼쪽 톱니이다.

우선 입력으로 회전하는 바퀴와 회전방향이 주어지면, 재귀 함수를 통해 모든 톱니바퀴의 회전 방향을 구했다.

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
// 각 톱니바퀴의 회전방향을 구한다.
void setRotation(int g, int d)
{
    rotation[g] = d;
    check[g] = true;
    // 현재 톱니바퀴의 왼쪽 톱니바퀴 세팅
    if (g - 1 > 0 && !check[g - 1])
    {
        // 현재 톱니바퀴가 회전하지 않으면
        if (d == 0)
            setRotation(g - 1, 0);
        // 맞닿은 극이 같다면
        else if (gear[g][6] == gear[g - 1][2])
            setRotation(g - 1, 0);
        // 맞닿은 극이 다르면
        else
            setRotation(g - 1, -d);
    }
    // 현재 톱니바퀴의 오른쪽 톱니바퀴 세팅
    if (g + 1 <= 4 && !check[g + 1])
    {
        // 현재 톱니바퀴가 회전하지 않으면
        if (d == 0)
            setRotation(g + 1, 0);
        // 맞닿은 극이 같다면
        else if (gear[g][2] == gear[g + 1][6])
            setRotation(g + 1, 0);
        // 맞닿은 극이 다르면
        else
            setRotation(g + 1, -d);
    }
}

그 후 회전을 수행해준다.
deque을 사용하면 회전을 간단하게 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 각 톱니바퀴 회전 수행
void rotate()
{
    for (int i = 1; i <= 4; i++)
    {
        if (rotation[i] == 0)
            continue;
        // 시계 방향 회전
        if (rotation[i] == 1)
        {
            int temp = gear[i].back();
            gear[i].pop_back();
            gear[i].push_front(temp);
        }
        // 반시계 회전
        else
        {
            int temp = gear[i].front();
            gear[i].pop_front();
            gear[i].push_back(temp);
        }
    }
}

소스 코드

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <vector>
#include <deque>
#include <cstring>
#include <cmath>

using namespace std;

// N = 0 , S = 1
vector<deque<int>> gear(5);
int rotation[5];
bool check[5];
int k;

// 각 톱니바퀴의 회전방향을 구한다.
void setRotation(int g, int d)
{
    rotation[g] = d;
    check[g] = true;
    // 현재 톱니바퀴의 왼쪽 톱니바퀴 세팅
    if (g - 1 > 0 && !check[g - 1])
    {
        // 현재 톱니바퀴가 회전하지 않으면
        if (d == 0)
            setRotation(g - 1, 0);
        // 맞닿은 극이 같다면
        else if (gear[g][6] == gear[g - 1][2])
            setRotation(g - 1, 0);
        // 맞닿은 극이 다르면
        else
            setRotation(g - 1, -d);
    }
    // 현재 톱니바퀴의 오른쪽 톱니바퀴 세팅
    if (g + 1 <= 4 && !check[g + 1])
    {
        // 현재 톱니바퀴가 회전하지 않으면
        if (d == 0)
            setRotation(g + 1, 0);
        // 맞닿은 극이 같다면
        else if (gear[g][2] == gear[g + 1][6])
            setRotation(g + 1, 0);
        // 맞닿은 극이 다르면
        else
            setRotation(g + 1, -d);
    }
}

// 각 톱니바퀴 회전 수행
void rotate()
{
    for (int i = 1; i <= 4; i++)
    {
        if (rotation[i] == 0)
            continue;
        // 시계 방향 회전
        if (rotation[i] == 1)
        {
            int temp = gear[i].back();
            gear[i].pop_back();
            gear[i].push_front(temp);
        }
        // 반시계 회전
        else
        {
            int temp = gear[i].front();
            gear[i].pop_front();
            gear[i].push_back(temp);
        }
    }
}

int getScore()
{
    int ans = 0;
    for (int i = 1; i <= 4; i++)
    {
        // 12시 방향이 S극
        if (gear[i][0] == 1)
        {
            ans += pow(2, i - 1);
        }
    }
    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    char n;
    for (int i = 1; i <= 4; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            cin >> n;
            gear[i].push_back(n - '0');
        }
    }

    cin >> k;
    int g, d;

    while (k--)
    {
        cin >> g >> d;
        memset(check, false, sizeof(check));
        setRotation(g, d);
        rotate();
    }
    int ans = getScore();
    cout << ans << '\n';

    return 0;
}

제출

제출