백준의 톱니바퀴(14891) 문제이다.

( 문제 바로가기 )


[ 문제설명 ]

- 입력으로 4개의 톱니바퀴의 상태가 주어진다. 각 톱니바퀴는 총 8개의 날을 가지고 있으며 가로로 일직선으로 4개가 놓여져

  있다. (톱니바퀴에는 N극과 S극이 있다.)

- 그리고 톱니바퀴를 회전시킬 명령어의 갯수와, 몇 번 톱니바퀴를 어떤 방향으로 돌릴지에 대한 정보가 입력으로 주어진다.

- 서로 이웃한 톱니바퀴(i-1 과 i와 i+1 번 톱니바퀴는 서로 이웃한 톱니바퀴) 의 맞닿은 부분이 같은 극이라면 이웃한 톱니바퀴

  는 움직이지 않지만, 다른 극이라면 돌리는 톱니바퀴의 반대방향으로 톱니바퀴가 돌아가게된다.

- 명령어의 갯수만큼 톱니바퀴를 돌린 후, 4개의 톱니바퀴의 12시 방향에 있는 극이 S극이면 각각의 점수를 부여 받게 되고

  그 점수를 출력하면 되는 문제이다.


[ 문제풀이 ]

1. 알고리즘에서 시뮬레이션은 정말 문제에서 주어진 조건 대로 그대로 구현을 하기만 하면 된다. 이 문제도 그대로 하면 된다.

2. 먼저 본인은 문제에서 사용되는 4개의 톱니바퀴를 Vector로 관리하였다. 입력으로 주어지는 톱니바퀴 4개의 상태를

   Vector에 넣어주었다. Vector<int> Wheel[4] 이렇게 선언해놓고, 각각의 톱니바퀴의 상태를 관리하였다.

   (톱니바퀴 번호가 1,2,3,4번이 아닌 0,1,2,3번으로 관리하였음 !)

3. 주어지는 명령어들도 Vector로 관리하였다. (본인이 Vector가 편해서 이렇게 관리했다는 거지, 꼭 이렇게 해야되는것이

   아니다.) 명령어들의 vector는 2개의 int형을 pair로 관리하였으며, (명령을 수행할 대상 톱니바퀴의번호 , 회전시킬방향)

   이렇게 2개의 데이터를 관리하였다.

   3-1) 4개의 톱니바퀴를 vector로 관리하였다고 했는데, 톱니바퀴의 12시방향부터 시계방향으로 값을 넣어주었다.

       그렇게 되면 톱니바퀴의 12시방향에 있는 값이 vector의 0번, 그 다음번이 1번... 이런식으로 가장 마지막 값은

       7번이 되도록 관리하였다.

   3-2) 3-1)처럼 관리하게 되면, 서로 이웃한 톱니바퀴를 쉽게 파악할 수 있다.

       A번 톱니바퀴를 기준으로 설명하자면, A번의 2번 극과, A+1번의 6번극이 서로 맞닿은 극이 되며,

       A번의 6번 극과, A-1번의 2번극이 서로 맞닿은 극이 된다. [ 그림참고 ]

그림과 같이 밑에 크게 검은글씨로 적힌 0,1,2,3은 톱니바퀴의 번호이고, 작은 빨강글씨로 적힌 0~7의 숫자는

각 톱니바퀴 안에서 배정받은 Index번호이다.


4. 톱니바퀴가 4개밖에 되지 않으므로 모든 경우에 대해서 다 구현해주었다.

   1) 명령을 수행할 톱니바퀴의 번호가 0번일 경우

     1. 0번의 2번 날과, 1번의 6번날을 비교. 만약 다르다면

     2. 1번의 2번 날과, 2번의 6번날을 비교. 만약 다르다면

     3. 2번의 1번 날과, 3번의 6번날을 비교. 만약 다르다면

       0번 2번 톱니바퀴는 명령어가 지시한 방향으로, 1번 3번 톱니바퀴는 지시한 반대방향으로 돌려주었다.

       위에서 말한 '만약 다르다면' 이라는 조건과 달리, 같아지는 구간이 있다면, 그 이후는 비교해 주지 않아도 된다.

       만약 0번의 2번 날과 1번의 6번 날이 다르고, 1번의 2번날과 2번의 6번날이 서로 같다고 생각해보자.

       1번은 0번과 맞닿은 극이 서로 다르기 때문에 돌아가야 하지만, 2번은 1번과 같기 때문에 움직이지 않아도 된다.

       자연스럽게 2번이 움직이지 않으므로 3번 톱니바퀴도 움직이지 않아도 된다.

    예를들어 명령을 수행할 톱니바퀴가 0번일 경우에 대해서만 설명을 했는데, 나머지 톱니바퀴도 저런식으로 비교해 주면

    된다. 나머지 부분에 대해서는 소스코드를 참고해보자.


[ 소스코드 ]

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include<iostream>
#include<vector>
#include<string>
 
#define endl "\n"
using namespace std;
 
int K;
 
vector<int> Wheel[4];
vector<pair<intint>> Cmd;
 
void Input()
{
    for (int i = 0; i < 4; i++)
    {
        string Inp;
        cin >> Inp;
        for (int j = 0; j < Inp.length(); j++)
        {
            int Tmp = Inp[j] - '0';
            Wheel[i].push_back(Tmp);
        }
    }
    // 1은 시계방향 -1은 반시계방향
    cin >> K;
    for (int i = 0; i < K; i++)
    {
        int Num, Dir;
        cin >> Num >> Dir;
        Num = Num - 1;
        Cmd.push_back(make_pair(Num, Dir));
    }
}
 
int Reverse_Direction(int d)
{
    if (d == 1return -1;
    else return 1;
}
 
void Actual_Turning(int n, int d)
{
    if (d == 1)
    {
        int Tmp = Wheel[n].at(7);
        for (int i = 7; i > 0; i--)
        {
            Wheel[n].at(i) = Wheel[n].at(i - 1);
        }
        Wheel[n].at(0= Tmp;
    }
    else if (d == -1)
    {
        int Tmp = Wheel[n].at(0);
        for (int i = 0; i < 7; i++)
        {
            Wheel[n].at(i) = Wheel[n].at(i + 1);
        }
        Wheel[n].at(7= Tmp;
    }
}
 
void Turn_Wheel(int n, int d)
{
    int nd = Reverse_Direction(d);
    if (n == 0)
    {
        if (Wheel[n].at(2!= Wheel[n + 1].at(6))
        {
            if (Wheel[n + 1].at(2!= Wheel[n + 2].at(6))
            {
                if (Wheel[n + 2].at(2!= Wheel[n + 3].at(6))
                {
                    Actual_Turning(n, d);
                    Actual_Turning(n + 1, nd);
                    Actual_Turning(n + 2, d);
                    Actual_Turning(n + 3, nd);
                }
                else
                {
                    Actual_Turning(n, d);
                    Actual_Turning(n + 1, nd);
                    Actual_Turning(n + 2, d);
                }
            }
            else
            {
                Actual_Turning(n, d);
                Actual_Turning(n + 1, nd);
            }
        }
        else
        {
            Actual_Turning(n, d);
        }
    }
    else if (n == 1)
    {
        if (Wheel[n].at(6!= Wheel[n-1].at(2))
        {
            Actual_Turning(n - 1, nd);
        }
 
        if (Wheel[n].at(2!= Wheel[n + 1].at(6))
        {
            if (Wheel[n + 1].at(2!= Wheel[n + 2].at(6))
            {
                Actual_Turning(n, d);
                Actual_Turning(n + 1, nd);
                Actual_Turning(n + 2, d);
            }
            else
            {
                Actual_Turning(n, d);
                Actual_Turning(n + 1, nd);
            }
        }
        else
        {
            Actual_Turning(n, d);
        }
    }
    else if (n == 2)
    {
        if (Wheel[n].at(2!= Wheel[n + 1].at(6))
        {
            Actual_Turning(n + 1, nd);
        }
 
        if (Wheel[n].at(6!= Wheel[n - 1].at(2))
        {
            if (Wheel[n - 1].at(6!= Wheel[n - 2].at(2))
            {
                Actual_Turning(n, d);
                Actual_Turning(n - 1, nd);
                Actual_Turning(n - 2, d);
            }
            else
            {
                Actual_Turning(n, d);
                Actual_Turning(n - 1, nd);
            }
        }
        else
        {
            Actual_Turning(n, d);
        }
    }
    else if (n == 3)
    {
        if (Wheel[n].at(6!= Wheel[n - 1].at(2))
        {
            if (Wheel[n - 1].at(6!= Wheel[n - 2].at(2))
            {
                if (Wheel[n - 2].at(6!= Wheel[n - 3].at(2))
                {
                    Actual_Turning(n, d);
                    Actual_Turning(n - 1, nd);
                    Actual_Turning(n - 2, d);
                    Actual_Turning(n - 3, nd);
                }
                else
                {
                    Actual_Turning(n, d);
                    Actual_Turning(n - 1, nd);
                    Actual_Turning(n - 2, d);
                }
            }
            else
            {
                Actual_Turning(n, d);
                Actual_Turning(n - 1, nd);
            }
        }
        else
        {
            Actual_Turning(n, d);
        }
    }
}
 
void Solution()
{
    for (int i = 0; i < Cmd.size(); i++)
    {
        int N = Cmd[i].first;
        int D = Cmd[i].second;
 
        Turn_Wheel(N, D);
    }
 
    int Answer = 0;
    if (Wheel[0].at(0== 1) Answer = Answer + 1;
    if (Wheel[1].at(0== 1) Answer = Answer + 2;
    if (Wheel[2].at(0== 1) Answer = Answer + 4;
    if (Wheel[3].at(0== 1) Answer = Answer + 8;
 
    cout << Answer << endl;
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
 
cs













+ Recent posts