기술 블로그

4013번 특이한 자석 본문

알고리즘 문제/SW Expert Academy

4013번 특이한 자석

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

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


푼 문제이지만, 나는 첫 번째 코드처럼 무식하게 풀었다.



재귀로 풀까 생각을 하였지만, 어떻게 구현해야 톱니의 각종 정보(회전 방향, 2번 째 값, 6번 째 값 등)를 넘겨 줄지 잘 몰라서


그냥 무식하게 구현하기로 하였었다. 맞긴 맞았으나 틀린 기분이다.



그래서 다른 풀이가 당연히 있을 것이라고, 생각하고 찾아 보았는데


역시나 재귀로 푸신 분이 계셔서 그 분 코드를 참고하였다.(2번 째 코드)






문제 : https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH


해설 : https://www.swexpertacademy.com/main/learn/course/subjectDetail.do?subjectId=AWJRz2T6DVYDFAXc






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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#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 T = 0;
 
    int input_num = 0;
    int rotation_count = 0;
    int gearNumber = 0, clockVector = 0;
 
    scanf("%d"&T);
 
    for (int tc = 1; tc <= T; tc++)
    {
        int result = 0;
 
        scanf("%d"&rotation_count);
 
        for (int i = 1; i <= 4; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                scanf("%d"&input_num);
 
                dq[i].push_back(input_num);
            }
        }
 
        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 %d\n", tc, result);
 
        for (int i = 1; i <= 4; i++)
        {
 
            if (!dq[i].empty()) dq[i].clear();
        }
    }
 
    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
103
104
105
106
107
108
109
110
111
112
#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, T = 0;
 
    scanf("%d"&T);
 
    for (int tc = 1; tc <= T; tc++)
    {
        int K = 0, result = 0;
 
        scanf("%d"&K);
 
        for (int i = 1; i <= 4; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                scanf("%d"&input_num);
 
                dq[i].push_back(input_num);
            }
        }
 
        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 %d\n", tc, result);
 
        for (int i = 1; i <= 4; i++)
        {
            if (!dq[i].empty()) dq[i].clear();
        }
    }
 
    return 0;
}
cs



728x90
반응형

'알고리즘 문제 > SW Expert Academy' 카테고리의 다른 글

2382번 미생물 격리  (0) 2018.08.29
1952번 수영장  (0) 2018.08.27
1953번 탈주범 검거  (0) 2018.08.25
2383번 점심 식사시간  (0) 2018.08.25
1267번 작업순서  (0) 2018.08.25