알고리즘/삼성 SW역량테스트

백준[14891] 톱니바퀴

vhxpffltm 2020. 3. 4. 23:48

삼성 역량테스트 기출문제중 하나이다.

 

문제의 출처는 아래와 같다.

 

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

 

이 문제는 구현으로 문제에서 하라는대로 하면 되는 문제이다. 회전을 구현한 다음 문제를 잘 읽어서 이해하여 톱니바퀴를 문제의 조건에 맞게끔 움직이면 된다.

 

먼저 회전부터 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
void rotate(int a) { // 반시계
    char tmp = arr[a][0];
    for (int i = 0; i < 8; i++) arr[a][i] = arr[a][i+1];
    arr[a][7= tmp;
    //printf("%s\n", arr[a]);
}
 
void rotate2(int a) {// 시계
    char tmp = arr[a][7];
    for (int i = 7; i > 0; i--) arr[a][i] = arr[a][i-1];
    arr[a][0= tmp;
    //printf("%s\n", arr[a]);
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

반복문을 사용하여 바로 옮길수 있다. 반시계일 경우 마지막값에 첫번째 값이 들어가야하기 때문에 미리 값을 저장한 후, 반복문 종료 후 값을 변경해준다. 시계방향일일 경우에도 반대로 생각하여 마찬가지로 값을 변경해준다.

 

주석으로 처리된 printf문을 사용하여 제대로 회전이 됐는지 항상 검사하고 넘어가자.

 

다음은 문제에서 주어진 내용인데 톱니의 마주치는 부분이 달라야 톱니가 이동한다. 톱니가 움직이면 연결된 다른 톱니들이 이동하는게 정상이지만, 문제에서는 처음에 마주치는 톱니의 조건을 만족해야 움직인다.

 

그래서 이 문제는 회전을 하기전에 먼저 마주치는 톱니가 회전가능한지를 살펴야한다. 그 다음에 조건에 따라 톱니를 회전시키고 이미 입력에서 주어진 해당 톱니바퀴는 무조건 움직이도록 만들어야한다.

 

필자의 순서는 아래와 같다. 입력을 받은 후

1) 현재 움직이지 않은 상태에서 움직여야 하는 톱니바퀴가 몇번인지 확인

2) 톱니바퀴를 움직인다. -> 회전 방향에 따라 움직여야 하는 톱니바퀴를 알맞게 움직인다,

   - 3번이 시계방향으로 움직였으면 2, 4번은 반시계로 움직여야 한다.

3) 움직여야 하는 톱니바퀴와 입력받은 톱니바퀴를 움직인다.

4) 반복횟수만큼 반복한다.

 

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
void check(int a,int b) {
    int v[5= { 0 }, dir = b , dir2 = b;
    v[a] = a;
    for (int i = a; i < 4; i++) {
        //cout << arr[1][2] << "  " << arr[i + 1][6] << endl;
        if (arr[i][2== arr[i+1][6]) break;
        else v[i + 1= i + 1;
    }
    for (int i = a; i > 1; i--) {
        if (arr[i][6== arr[i - 1][2]) break;
        else v[i - 1= i - 1;
    }
    //움직이는 톱니바퀴인지 검사, 움직이면 v에 저장
 
 
    //for (int i = 1; i <= 4; i++) cout << v[i] << "  ";
    //printf("\n\n");
    for (int i = a; i < 4; i++) {
        if (v[i + 1== 0break;
        if ((dir*-1== 1) rotate2(i + 1);
        else rotate(i + 1);
        dir = dir * -1;
    }
    for (int i = a; i > 1; i--) {
        if (v[i - 1== 0break;
        if ((dir2*-1== 1) rotate2(i - 1);
        else rotate(i - 1);
        dir2 = dir2 * -1;
    }
    //v를 순회하여 톱니를 조건에 맞게 톱니 
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

위 코드처럼 톱니바퀴를 먼저 검사하고 움직여야 하는 톱니바퀴를 움직이는데 방향에 따라 알맞게 움직인다.

다행히 1과 -1로 방향이 주어져있기에 (방향*-1) 로 시계방향과 반시계방향을 쉽게 조절할 수 있다. 

반복문이 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
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<iterator>
#include<deque>
#include<sstream>
#pragma warning(disable:4996)
using namespace std;
 
char arr[6][10];
int k,ans;
 
void rotate(int a) { // 반시계
    char tmp = arr[a][0];
    for (int i = 0; i < 8; i++) arr[a][i] = arr[a][i+1];
    arr[a][7= tmp;
    //printf("%s\n", arr[a]);
}
 
void rotate2(int a) {// 시계
    char tmp = arr[a][7];
    for (int i = 7; i > 0; i--) arr[a][i] = arr[a][i-1];
    arr[a][0= tmp;
    //printf("%s\n", arr[a]);
}
 
void check(int a,int b) {
    int v[5= { 0 }, dir = b , dir2 = b;
    v[a] = a;
    for (int i = a; i < 4; i++) {
        //cout << arr[1][2] << "  " << arr[i + 1][6] << endl;
        if (arr[i][2== arr[i+1][6]) break;
        else v[i + 1= i + 1;
    }
    for (int i = a; i > 1; i--) {
        if (arr[i][6== arr[i - 1][2]) break;
        else v[i - 1= i - 1;
    }
    
    //for (int i = 1; i <= 4; i++) cout << v[i] << "  ";
    //printf("\n\n");
    for (int i = a; i < 4; i++) {
        if (v[i + 1== 0break;
        if ((dir*-1== 1) rotate2(i + 1);
        else rotate(i + 1);
        dir = dir * -1;
    }
    for (int i = a; i > 1; i--) {
        if (v[i - 1== 0break;
        if ((dir2*-1== 1) rotate2(i - 1);
        else rotate(i - 1);
        dir2 = dir2 * -1;
    }
    
}
 
int main()
{
    for (int i = 1; i <= 4; i++scanf("%s", arr[i]);
    cin >> k;
    for (int i = 0; i < k; i++) {
        int a, b;
        scanf("%d %d"&a, &b);
        check(a, b);
        if (b == 1) rotate2(a);
        else rotate(a);
        //for (int i = 1; i <= 4; i++)printf("%s\n", arr[i]);
    }
    for (int i = 1,j=1; i <= 4; i++,j=j*2) {
        if (arr[i][0== '1') ans = ans + j;
    }
    printf("%d", ans);
    
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

'알고리즘 > 삼성 SW역량테스트' 카테고리의 다른 글

[백준] 15661 링크와 스타트  (0) 2020.06.11
[백준] 17281 야구?  (0) 2020.05.15
백준[17144] 미세먼지 안녕!  (0) 2020.02.27
백준 [17779] 게리맨더링2  (0) 2019.12.08
백준 [17822] 원판 돌리기  (0) 2019.11.03