두 번째 풀이입니다. 예전과는 어떻게 얼마나 달라졌는지 궁금해서 한번 더 풀어보았습니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRQm6qfL0DFAUo 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 벽돌 보드를 입력받는다.

2. N개의 구슬을 쏘아서 가장 많은 벽돌이 제거되는 경우를 찾고, 그 때 남은 벽돌의 개수를 출력한다.

 

<해법>

1. 알고리즘 선택하기

=> 구슬을 쏘는 모든 경우를 다 해보아야 합니다. 따라서, 저는 브루트포스를 선택했습니다. 

 

2. 벽돌 깨트리기

=> 저는 DFS를 선택했습니다. 4방향을 벽돌의 power만큼 탐색하면서 벽돌을 깨트렸습니다. 사실 구현은 DFS, BFS 큰 상관이 없다고 생각합니다.

 

3. 벽돌 내리기

=> 벽돌을 깨트렸으면, 이제 벽돌을 빈공간으로 내려야합니다. 저는 큐(Queue)를 선택했습니다. 아래서 부터 벽돌인 것만 큐에 차례로 담고, 나중에 다시 벽돌을 쌓는 개념으로 구현하였습니다. 자세한 구현은 코드의 fallBrick() 함수를 참조해주세요.

 

4. 구현 전 총정리

=> 아래는 구현 전 정리한 생각입니다.

(1) 구슬을 쏘는 위치는 재귀함수로 구현한다. 최악의 경우 12P4 이므로, 시간초과하지 않는다.

(2) 구슬의 위치를 다 결정하고 시뮬레이션을 할까, 구슬의 위치를 정할 때마다 시뮬레이션을 할까?

: 구슬의 위치를 정할 때마다 시뮬레이션을 진행한다. 구슬의 위치 [1,2,3,4]와 [1,2,3,5]는 구슬을 [1,2,3] 떨어트렸을 때까지 상황이 동일하다. 따라서, 시간을 줄이기 위해 구슬의 위치 정하고 바로 구슬을 떨어트려본다.

(3) 벽돌 깨트리는 것은 재귀함수로 구현한다.

(4) 벽돌 내릴 때는 큐를 이용해 구현한다.

(5) 남은 벽돌 개수의 최소를 구하는 것이므로, 반대로 얘기하면 깨트린 벽돌 개수의 최대를 구하는 것과 같다. 따라서, (처음 벽돌 개수) - (깨트린 벽돌 개수 max)를 출력한다.

자세한 구현은 아래 코드를 참조해주세요.

 

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
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#define INF 987654321
 
using namespace std;
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
int N, W, H;
int map[15][12];
int totalBricks;
int answer;
 
bool isInner(int x, int y) {
    if (x < 0 || y < 0 || x >= H || y >= W) return false;
    return true;
}
 
int removeBrick(int x, int y) {
    int power = map[x][y];
    map[x][y] = 0;
    int ret = 1;
    for (int i = 0; i < 4; i++) {
        for (int j = 1; j < power; j++) {
            int nx = x + (dx[i] * j);
            int ny = y + (dy[i] * j);
            if (!isInner(nx, ny)) break;
            if (map[nx][ny] > 0) {
                ret += removeBrick(nx, ny);
            }
        }
    }
    return ret;
}
 
void fallBrick() {
    for (int j = 0; j < W; j++) {
        queue<int> q;
        for (int i = H - 1; i >= 0; i--) {
            if (map[i][j] > 0) q.push(map[i][j]);
            map[i][j] = 0;
        }
        int col = H - 1;
        while (!q.empty()) {
            map[col][j] = q.front();
            q.pop();
            col--;
        }
    }
}
 
int simulation(int col) {
    int removedBricks = 0;
    for (int i = 0; i < H; i++) {
        if (map[i][col] > 0) {
            removedBricks = removeBrick(i, col);
            fallBrick();
            break;
        }
    }
    return removedBricks;
}
 
int selectBallPos(int cnt) {
    if (cnt == N) return 0;
 
    int ret = 0;
    int backup[15][12];
    memcpy(backup, map, sizeof(backup));
    for (int i = 0; i < W; i++) {
        int removedBricks = simulation(i);
        ret = max(ret, selectBallPos(cnt + 1+ removedBricks);
        memcpy(map, backup, sizeof(map));
    }
    return ret;
}
 
void solution() {
    answer = totalBricks - selectBallPos(0);
}
 
int main() {
    int test_case;
    int T;
    cin >> T;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        N = 0, W = 0, H = 0;
        memset(map, 0sizeof(map));
        totalBricks = 0;
        answer = 0;
 
        //입력
        cin >> N >> W >> H;
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                cin >> map[i][j];
                if (map[i][j] > 0) totalBricks++;
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    //종료
    return 0;
}

 

브루트포스, DFS, 시뮬레이션에 대해 알아볼 수 있는 문제였습니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV141J8KAIcCFAYD&categoryId=AV141J8KAIcCFAYD&categoryType=CODE&problemTitle=1232&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 트리를 입력받는다

2. 트리를 연산한 결과를 출력한다.

 

<해법>

1. 트리를 구현하는 방법

=> 저는 노드 구조체를 만들어서 구현하였습니다. 구조체에는 data와 왼쪽 자식, 오른쪽자식의 index가 있습니다.

 

2. 트리를 연산하는 방법

=> 저는 트리를 후위순회 하였습니다. 또한, 숫자는 leaf노드에만 존재하므로 노드의 데이터가 연산자면 자식노드들을 탐색하고, 숫자노드면 바로 숫자 데이터를 return하는 것으로 구현하였습니다.

 

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
#include <iostream>
#include <vector>
#include <string>
 
using namespace std;
 
struct node {
    string data;
    int leftNode, rightNode;
};
 
int N;
node arr[1001];
int answer;
 
bool isOper(string s) {
    if (s == "+" || s == "-" || s == "*" || s == "/"return true;
    return false;
}
 
double calculate(double a, string oper, double b) {
    double output = 0;
    if (oper == "+") output = a + b;
    else if (oper == "-") output = a - b;
    else if (oper == "*") output = a * b;
    else output = a / b;
    return output;
}
 
double postOrder(int idx) {
    if (!isOper(arr[idx].data)) return stoi(arr[idx].data);
 
    double ret = 0;
    ret = calculate(postOrder(arr[idx].leftNode), arr[idx].data, postOrder(arr[idx].rightNode));
    return ret;
}
 
void solution() {
    answer = postOrder(1);
}
 
int main() {
    int test_case;
    int T;
    T = 10;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        N = 0;
        for (int i = 0; i < 1001; i++) arr[i] = { "",0,0 };
        answer = 0;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            int idx;
            string data;
            cin >> idx >> data;
            arr[idx].data = data;
            if (isOper(data)) {
                int leftNode, rightNode;
                cin >> leftNode >> rightNode;
                arr[idx].leftNode = leftNode, arr[idx].rightNode = rightNode;
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    //종료
    return 0;
}

 

자료구조 트리와 재귀함수에 대해 알아볼 수 있는 문제였습니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV141176AIwCFAYD&categoryId=AV141176AIwCFAYD&categoryType=CODE&problemTitle=1233&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 트리 정보를 입력받는다.

2. 해당 트리 연산식의 유효성을 출력한다.

 

<해법>
1. 트리 연산식의 유효성을 판단하는 방법

=> 계산되는 방법을 살펴보면, 연산자 노드는 자식이 있어야하고 숫자 노드는 자식이 없어야합니다. 또한 연산자 노드는 자식이 꼭 2개여야 합니다. 저는 입력받을 때, 연산자이면 자식이 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
#include <iostream>
 
using namespace std;
 
int N;
bool answer;
 
bool isOper(char c) {
    if (c == '+' || c == '-' || c == '*' || c == '/'return true;
    return false;
}
 
int main() {
    int test_case;
    int T;
    T = 10;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        N = 0;
        answer = true;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            int idx;
            char data;
            cin >> idx >> data;
 
            int cnt = 0;
            if (isOper(data)) cnt = 2;
            int childCnt = 0;
            while (getc(stdin) == ' ') {
                int trash;
                cin >> trash;
                childCnt++;
            }
            if (childCnt != cnt) answer = false;
        }
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    //종료
    return 0;
}

 

자료구조 트리에 대해 알아볼 수 있는 문제였습니다.

'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글

[C++] SWEA 5656 - 벽돌 깨기(2)  (0) 2023.01.02
[C++] SWEA 1232 - 사칙연산  (1) 2022.12.31
[C++] SWEA 1231 - 중위순회  (0) 2022.12.31
[C++] SWEA 1230 - 암호문3  (0) 2022.12.24
[C++] SWEA 5644 - 무선 충전(2)  (0) 2022.12.24

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV140YnqAIECFAYD&categoryId=AV140YnqAIECFAYD&categoryType=CODE&problemTitle=1231&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 트리 정보를 입력받는다.

2. 트리를 중위순회해서 얻은 문자열을 출력한다.

 

<해법>

1. 트리 정보 저장 방법

=> 문제에서 트리는 완전 이진탐색으로 주어집니다. 따라서, 배열로 구현할 수 있고 각 노드의 자식들은 (본인 index * 2), (본인 index * 2 + 1)로 나타낼 수 있습니다.(루트노드를 index 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
#include <iostream>
#include <string.h>
 
using namespace std;
 
int N;
char tree[101];
string answer;
 
string inOrderSearch(int idx) {
    if (idx > N) return "";
 
    string ret = "";
    ret = inOrderSearch(idx * 2+ tree[idx] + inOrderSearch((idx * 2+ 1);
    return ret;
}
 
void solution() {
    answer = inOrderSearch(1);
}
 
int main() {
    int test_case;
    int T;
    T = 10;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        N = 0;
        memset(tree, NULLsizeof(tree));
        answer = "";
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            int idx;
            char c;
            cin >> idx >> c;
            tree[idx] = c;
 
            int trash;
            while (getc(stdin) == ' ') {
                cin >> trash;
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    //종료
    return 0;
}

 

중위순회에 대해 알아볼 수 있는 문제였습니다.

'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글

[C++] SWEA 1232 - 사칙연산  (1) 2022.12.31
[C++] SWEA 1233 - 사칙연산 유효성 검사  (0) 2022.12.31
[C++] SWEA 1230 - 암호문3  (0) 2022.12.24
[C++] SWEA 5644 - 무선 충전(2)  (0) 2022.12.24
[C++] SWEA 1227 - 미로2  (0) 2022.12.24

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14zIwqAHwCFAYD 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 암호문과 명령어를 입력받는다.

2. 암호문을 명령어에 맞게 수정하고, 암호문의 처음 10개의 숫자를 출력한다.

 

<해법>

1. 자료구조 선택하기

=> 저는 list 자료구조를 선택하였습니다. I 명령어는 list의 splice를, D는 erase를, A는 push_back를 사용하여 구현하였습니다.

 

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
#include <iostream>
#include <list>
 
using namespace std;
 
int N;
list<int> code;
 
int main() {
    int test_case;
    int T;
    T = 10;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        N = 0;
        code.clear();
 
        //입력 및 해법
        cin >> N;
        for (int i = 0; i < N; i++) {
            int num = 0;
            cin >> num;
            code.push_back(num);
        }
        cin >> N;
        for (int i = 0; i < N; i++) {
            char cmd;
            int x, y, s;
            cin >> cmd;
            if (cmd == 'I') {
                cin >> x >> y;
                list<int> add;
                for (int j = 0; j < y; j++) {
                    cin >> s;
                    add.push_back(s);
                }
                auto iter = code.begin();
                while (x--) iter++;
                code.splice(iter, add);
            }
            else if (cmd == 'D') {
                cin >> x >> y;
                auto iter = code.begin();
                while (x--) iter++;
                while (y--) {
                    iter = code.erase(iter);
                }
            }
            else {
                cin >> y;
                for (int j = 0; j < y; j++) {
                    cin >> s;
                    code.push_back(s);
                }
            }
        }
 
        //출력
        cout << "#" << test_case << " ";
        for (int i = 0; i < 10; i++) {
            cout << code.front() << " ";
            code.pop_front();
        }
        cout << "\n";
    }
 
    //종료
    return 0;
}

 

리스트 자료구조에 대해 알아볼 수 있는 문제였습니다.

두 번째 풀이입니다. 예전과는 어떻게 얼마나 달라졌는지 궁금해서 한번 더 풀어보았습니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRDL1aeugDFAUo&categoryId=AWXRDL1aeugDFAUo&categoryType=CODE&problemTitle=5644&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 배터리 BC 정보와 사용자 이동 정보를 입력받는다.

2. 사용자가 충전한 양의 합의 최댓값을 출력한다.

 

<해법>

1. 사용자가 충전한 양의 합이 최대가 되는 BC 선택하기

=> 사용자 한명씩 모두 BC를 선택해보아야 합니다. 따라서, 저는 재귀함수를 이용해서 브루트포스를 구현하였습니다.

 

2. 구현 전 총정리

=> 아래는 구현 전 정리한 생각입니다.

(1) 주어진 사용자 이동 정보를 이용해 시뮬레이션을 진행한다.

(2) 사용자가 이동할 때마다, 재귀함수를 이용해 충전한 양의 최댓값을 구한다.

(3) 충전한 양의 합을 출력한다.

자세한 구현은 아래 코드를 참조해주세요.

 

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
#include <iostream>
#include <string.h>
#include <algorithm>
 
using namespace std;
 
struct pos {
    int x, y;
};
 
struct bc {
    pos p;
    int c;
    int power;
};
 
int dx[] = { 0,-1,0,1,0 };
int dy[] = { 0,0,1,0,-1 };
 
int M, A;
int dir[2][101];
bc BC[8];
pos user[2];
bool visited[8];
int answer;
 
bool canCharge(pos p, int num) {
    if (abs(p.x - BC[num].p.x) + abs(p.y - BC[num].p.y) <= BC[num].c) return true;
    return false;
}
 
int chargeAmount(int idx) {
    if (idx == 2return 0;
 
    int ret = 0;
    for (int i = 0; i < A; i++) {
        if (canCharge(user[idx], i) && !visited[i]) {
            visited[i] = true;
            ret = max(ret, chargeAmount(idx + 1+ BC[i].power);
            visited[i] = false;
        }
    }
    ret = max(ret, chargeAmount(idx + 1));
    return ret;
}
 
int simulation() {
    int output = 0;
    user[0].x = 1, user[0].y = 1, user[1].x = 10, user[1].y = 10;
    
    for (int time = 0; time <= M; time++) {
        for (int i = 0; i < 2; i++) {
            user[i].x += dx[dir[i][time]];
            user[i].y += dy[dir[i][time]];
        }
        output += chargeAmount(0);
    }
   
    return output;
}
 
void solution() {
    answer = simulation();
}
 
int main() {
    int test_case;
    int T;
    cin >> T;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        M = 0, A = 0;
        memset(dir, 0sizeof(dir));
        for (int i = 0; i < 8; i++) {
            BC[i] = { 0,0,0,0 };
        }
        for (int i = 0; i < 2; i++) {
            user[i] = { 0,0 };
        }
        memset(visited, falsesizeof(visited));
        answer = 0;
 
        //입력
        cin >> M >> A;
        for (int i = 0; i < 2; i++) {
            for (int j = 1; j <= M; j++) {
                cin >> dir[i][j];
            }
        }
        for (int i = 0; i < A; i++) {
            int x = 0, y = 0, c = 0, power = 0;
            cin >> y >> x >> c >> power;
            BC[i] = { {x,y},c,power };
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    //종료
    return 0;
}

 

시뮬레이션과 DFS에 대해 알아볼 수 있는 문제였습니다.

'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글

[C++] SWEA 1231 - 중위순회  (0) 2022.12.31
[C++] SWEA 1230 - 암호문3  (0) 2022.12.24
[C++] SWEA 1227 - 미로2  (0) 2022.12.24
[C++] SWEA 1225 - 암호생성기  (0) 2022.12.24
[C++] SWEA 5650 - 핀볼 게임(2)  (0) 2022.12.23

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14wL9KAGkCFAYD&categoryId=AV14wL9KAGkCFAYD&categoryType=CODE&problemTitle=1227&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 미로를 입력받는다.

2. 미로 출발점부터 도착점까지 갈 수 있는지 출력한다.

 

<해법>

1. 알고리즘 선택하기

=> 길찾기 알고리즘으로 DFS(스택, 재귀함수), BFS(큐)가 있습니다. 모든 방법으로 풀이가 가능합니다(모든 방법으로 풀어보았습니다). 저는 미로 1에서 DFS(재귀함수)를 이용한 코드를 올렸으므로, 이번에는 BFS를 이용한 코드를 올리겠습니다.

 

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
#include <iostream>
#include <string.h>
#include <queue>
 
using namespace std;
 
struct pos {
    int x, y;
};
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
int trash;
char map[100][100];
pos start;
bool answer;
 
bool isInner(pos p) {
    if (p.x < 0 || p.y < 0 || p.x >= 100 || p.y >= 100return false;
    return true;
}
 
bool findRoute() {
    queue<pos> q;
    bool visited[100][100];
    memset(visited, falsesizeof(visited));
 
    q.push(start);
    visited[start.x][start.y] = true;
    while (!q.empty()) {
        pos cur = q.front();
        q.pop();
        if (map[cur.x][cur.y] == '3'return true;
        for (int i = 0; i < 4; i++) {
            pos nxt = cur;
            nxt.x += dx[i];
            nxt.y += dy[i];
            if (isInner(nxt) && map[nxt.x][nxt.y] != '1' && !visited[nxt.x][nxt.y]) {
                q.push(nxt);
                visited[nxt.x][nxt.y] = true;
            }
        }
    }
    return false;
}
 
void solution() {
    answer = findRoute();
}
 
int main() {
    int test_case;
    int T;
    T = 10;
    for (test_case = 1; test_case <= T; test_case++) {
        //초기화
        trash = 0;
        memset(map, '0'sizeof(map));
        start = { 0,0 };
        answer = false;
 
        //입력
        cin >> trash;
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                cin >> map[i][j];
                if (map[i][j] == '2') {
                    start = { i,j };
                }
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

BFS에 대해 알아볼 수 있는 문제였습니다.

'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글

[C++] SWEA 1230 - 암호문3  (0) 2022.12.24
[C++] SWEA 5644 - 무선 충전(2)  (0) 2022.12.24
[C++] SWEA 1225 - 암호생성기  (0) 2022.12.24
[C++] SWEA 5650 - 핀볼 게임(2)  (0) 2022.12.23
[C++] SWEA 1226 - 미로1  (0) 2022.12.21

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14uWl6AF0CFAYD&categoryId=AV14uWl6AF0CFAYD&categoryType=CODE&problemTitle=1225&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

<풀이>

1. 8개의 숫자를 입력받는다.

2. 주어진 작업을 종료된 후 8개의 숫자를 출력한다.

 

<해법>

1. 하나하나씩 다 해봐야 할까?

=> 사실 이 문제를 푸는 것은 간단합니다. 큐를 이용해서 주어진 조건에 맞게 구현하는 것은 어렵지 않은 일입니다. 하지만, 테스트케이스처럼 큰 숫자가 나올경우 너무 오래걸릴거란 생각이 듭니다. 꼭 하나하나씩 1,2,3,4,5,1,2,3,4,5... 순서로 빼봐야할까요? 아닙니다. 잘 생각해보면, 8사이클이 돌 경우 모든 숫자에서 1+2+3+4+5 = 15의 숫자가 빠지게 됩니다. 따라서, 모든 숫자에서 15씩 동일하게 여러번 뺄 수 있습니다. 그렇지만, 여기서 조금 더 생각해서 숫자가 15,30,45 등등 15의 배수일 경우를 생각해야합니다. 이 때는 0이 될때까지 빼면 안됩니다. 왜냐하면 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
#include <iostream>
#include <string.h>
#include <queue>
#define INF 987654321
 
using namespace std;
 
int trash;
int arr[8];
queue<int> q;
int minimum;
 
void solution() {
    int div = minimum / 15;
    int remainder = minimum % 15;
    div = (remainder == 0) ? div - 1 : div;
    for (int i = 0; i < 8; i++) {
        arr[i] -= (15 * div);
    }
    for (int i = 0; i < 8; i++) {
        q.push(arr[i]);
    }
    while (true) {
        for (int i = 1; i <= 5; i++) {
            int tmp = q.front() - i;
            q.pop();
            q.push((tmp <= 0 ? 0 : tmp));
            if (tmp <= 0return;
        }
    }
}
 
int main() {
    int test_case;
    int T;
 
    T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        trash = 0;
        memset(arr, 0sizeof(arr));
        while (!q.empty()) q.pop();
        minimum = INF;
 
        //입력
        cin >> trash;
        for (int i = 0; i < 8; i++) {
            int num;
            cin >> num;
            arr[i] = num;
            minimum = min(minimum, num);
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " ";
        while (!q.empty()) {
            cout << q.front() << " ";
            q.pop();
        }
        cout << "\n";
    }
 
    //종료
    return 0;
}

 

수학적인 사고와 구현에 대해 알아볼 수 있었습니다.

'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글

[C++] SWEA 5644 - 무선 충전(2)  (0) 2022.12.24
[C++] SWEA 1227 - 미로2  (0) 2022.12.24
[C++] SWEA 5650 - 핀볼 게임(2)  (0) 2022.12.23
[C++] SWEA 1226 - 미로1  (0) 2022.12.21
[C++] SWEA 1224 - 계산기3  (0) 2022.12.21

+ Recent posts