기술 블로그

14891번 톱니바퀴 본문

알고리즘 문제/BOJ

14891번 톱니바퀴

parkit 2018. 8. 24. 16:47
728x90
반응형

삼성 SW 역량 테스트 기출 문제이다.


동일한 문제 풀이 : http://hsdevelopment.tistory.com/23







https://www.acmicpc.net/problem/14891







1. 무식하게 풀기

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
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
 
using namespace std;
 
deque<int> dq[5];
 
int N = 0;
 
/*
회전 시킨 톱니 바퀴가 1번이라면,
1. 2번 검사 → 3번 검사 → 4번 검사
회전 시킨 톱니 바퀴가 2번이라면,
1. 1번 검사
2. 3번 검사 → 4번 검사
회전 시킨 톱니 바퀴가 3번이라면,
1. 2번 검사 → 1번 검사
2. 4번 검사
회전 시킨 톱니 바퀴가 4번이라면,
1. 3번 검사 → 2번 검사 → 1번 검사
*/
 
void onlyRotate(int gear, int clock)
{
    if (clock == 1// clockwise
    {
        dq[gear].push_front(dq[gear].back());
 
        dq[gear].pop_back();
    }
    else if (clock == -1// counterclockwise
    {
        dq[gear].push_back(dq[gear].front());
 
        dq[gear].pop_front();
    }
}
 
int Do_Rotate(int gear, int clcok)
{
    if (clcok == 1)
    {
        onlyRotate(gear, -1);
 
        return -1;
    }
    else if (clcok == -1)
    {
        onlyRotate(gear, 1);
 
        return 1;
    }
}
 
int gear_left(int gear)
{
    int ret = 0;
 
    ret = dq[gear][6];
 
    return ret;
}
 
int gear_right(int gear)
{
    int ret = 0;
 
    ret = dq[gear][2];
 
    return ret;
}
 
void Rotate_Gear(int gear, int clock)
{
    int left = dq[gear][6]; // 입력 받은 톱니 바퀴의 왼쪽
 
    int right = dq[gear][2]; // 입력 받은 톱니 바퀴의 오른쪽 
 
    if (clock == 1// 시계 방향이라면
    {
        dq[gear].push_front(dq[gear].back());
 
        dq[gear].pop_back();
    }
    else if (clock == -1// 반시계 방향이라면
    {
        dq[gear].push_back(dq[gear].front());
 
        dq[gear].pop_front();
    }
 
    if (gear == 1)
    {
        // 1 오 vs 2 왼
        if (right == gear_left(2)) return// 1오와 2왼이 같다면 리턴
        int r = gear_right(2); // 다르면 2를 회전 시키기 전에 2오를 저장한다.
        int pos = Do_Rotate(2, clock); // 다르면 2회전
 
        // 2 오 vs 3 왼
        if (r == gear_left(3)) return// 2오와 3왼이 같다면 리턴
        r = gear_right(3); // 다르면 3을 회전 시키기 전에 3오를 저장한다.
        pos = Do_Rotate(3, pos); // 3회전
 
        // 3 오 vs 4 왼
        if (r == gear_left(4)) return// 3오와 4왼이 같다면 리턴
        Do_Rotate(4, pos); // 다르면 4회전
    }
    else if (gear == 2)
    {
        // 1 오 vs 2 왼 
        if (gear_right(1!= left) onlyRotate(1-clock);
        
        // 2 오 vs 3 왼
        if (right == gear_left(3)) return;
        int r = gear_right(3);
        int pos = Do_Rotate(3, clock);
 
        // 3 오 vs 4 왼
        if (r == gear_left(4)) return;
        Do_Rotate(4, pos);
    }
    else if (gear == 3)
    {
        // 3 오 vs 4 왼
        if (right != gear_left(4)) onlyRotate(4-clock);
        
        // 2 오 vs 3 왼
        if (gear_right(2== left) return;
        int l = gear_left(2);
        int pos = Do_Rotate(2, clock);
 
        // 1 오 vs 2 왼
        if (gear_right(1== l) return;
        Do_Rotate(1, pos);
    }
    else if (gear == 4)
    {
        // 3 오 vs 4 왼    
        if (gear_right(3== left) return;
        int l = gear_left(3);
        int pos = Do_Rotate(3, clock);
 
        // 2 오 vs 3 왼
        if (gear_right(2== l) return;
        l = gear_left(2);
        pos = Do_Rotate(2, pos);
 
        // 1 오 vs 2 왼
        if (gear_right(1== l) return;
        Do_Rotate(1, pos);
    }
}
 
int main(void)
{
    int result = 0;
    int input_num[8= { 0, };
    int rotation_count = 0;
    int gearNumber = 0, clockVector = 0;
 
    for (int i = 1; i <= 4; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            scanf("%1d"&input_num[j]);
 
            dq[i].push_back(input_num[j]);
        }
    }
 
    scanf("%d"&rotation_count);
 
    while (rotation_count--)
    {
        scanf("%d %d"&gearNumber, &clockVector);
 
        Rotate_Gear(gearNumber, clockVector);
    }
 
    for (int i = 1; i <= 4; i++)
    {
        int score = dq[i].front();
 
        if (score == 0// N
        {
            result += 0;
        }
        else if (score == 1// S
        {
            if (i == 3) result += i + 1;
            else if (i == 4)
            {
                result += 2 * i;
            }
            else
            {
                result += i;
            }
        }
    }
 
    printf("%d\n", result);
 
    return 0;
}
cs








2. 재귀로 풀기

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
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <math.h>
#include <algorithm>
 
using namespace std;
 
deque<int> dq[5];
 
void rotate(int gear_number, int clock_direction, int leftOrright)
{
    if (clock_direction == 1// 시계 방향
    {
        // leftOrright가 0일 때는 오른쪽으로만
        if (gear_number + 1 <= 4 && dq[gear_number][2!= dq[gear_number + 1][6&& (leftOrright == 0 || leftOrright == 2))
        {
            rotate(gear_number + 1-clock_direction, 0);
        }
 
        // leftOrright가 1일 때는 왼쪽으로만
        if (gear_number - 1 >= 1 && dq[gear_number][6!= dq[gear_number - 1][2&& (leftOrright == 1 || leftOrright == 2))
        {
            rotate(gear_number - 1-clock_direction, 1);
        }
 
        dq[gear_number].push_front(dq[gear_number].back());
        dq[gear_number].pop_back();
    }
    else if (clock_direction == -1// 반 시계 방향
    {
        // leftOrright가 0일 때는 오른쪽으로만
        if (gear_number + 1 <= 4 && dq[gear_number][2!= dq[gear_number + 1][6&& (leftOrright == 0 || leftOrright == 2))
        {
            rotate(gear_number + 1-clock_direction, 0);
        }
 
        // leftOrright가 1일 때는 왼쪽으로만
        if (gear_number - 1 >= 1 && dq[gear_number][6!= dq[gear_number - 1][2&& (leftOrright == 1 || leftOrright == 2))
        {
            rotate(gear_number - 1-clock_direction, 1);
        }
 
        dq[gear_number].push_back(dq[gear_number].front());
        dq[gear_number].pop_front();
    }
}
 
int main(void)
{
    int input_num = 0, gn = 0, clock = 0;
 
    int K = 0, result = 0;
 
    for (int i = 1; i <= 4; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            scanf("%1d"&input_num);
 
            dq[i].push_back(input_num);
        }
    }
 
    scanf("%d"&K);
 
    while (K--)
    {
        scanf("%d %d"&gn, &clock);
 
        rotate(gn, clock, 2);
    }
 
    for (int i = 1; i <= 4; i++)
    {
        int score = dq[i].front();
 
        if (score == 0// N
        {
            result += 0;
        }
        else if (score == 1// S
        {
            if (i == 3) result += i + 1;
            else if (i == 4)
            {
                result += 2 * i;
            }
            else
            {
                result += i;
            }
        }
    }
 
    printf("%d\n", result);
 
    return 0;
}
cs


728x90
반응형

'알고리즘 문제 > BOJ' 카테고리의 다른 글

2589번 보물섬  (0) 2018.08.25
2174번 로봇 시뮬레이션  (0) 2018.08.25
14889번 스타트와 링크  (0) 2018.08.24
6593번 상범 빌딩  (0) 2018.08.24
15684번 사다리 조작  (0) 2018.08.23