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

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의

www.acmicpc.net

<풀이>

1. 집의 상태를 입력받는다.

2. 파이프를 한쪽 끝으로 옮길 수 있는 방법의 수를 출력한다.

 

<해법>

1. 알고리즘 선택하기

=> 모든 방법의 수를 구해야하므로, 파이프를 놓는 모든 경우를 다 해보아야합니다. 따라서, 저는 백트래킹을 선택하였습니다.(파이프를 놓을 수 있는 유망한 경우에만 탐색할 것이므로)

 

2. 파이프 옮기기

=> 파이프는 종류에 따라 (1)다음에 놓을 파이프가 다르고, (2)파이프를 놓을 수 있는 공간이 다릅니다. 따라서, 저는 위 두가지 경우를 배열로 미리 만들어 놓았습니다.(코드의 connect[][]와 check[][] 참조)

 

3. 최적화 할 수 있을까?

=> 이 문제는 작은 부분 문제에서 구한 최적의 답을 이용해서 큰 문제의 최적의 답을 구할 수 있습니다. 따라서, 저는 DP를 이용하여 최적화 하였습니다.

 

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>
 
using namespace std;
 
int dx[] = { 0,1,1 };
int dy[] = { 1,0,1 };
int connect[3][3= { //파이프 끼리 연결 가능 여부
    {1,0,1},          
    {0,1,1},
    {1,1,1},
};
int check[3][3= { //파이프를 놓을 때, 확인해야하는 부분
    {1,0,0},
    {0,1,0},
    {1,1,1}
};
 
int N;
int map[16][16];
int cache[16][16][3];
int answer;
 
bool isInner(int x, int y) {
    if (x < 0 || y < 0 || x >= N || y >= N) return false;
    return true;
}
 
bool canMove(int x, int y, int type) {
    for (int i = 0; i < 3; i++) {
        if (!check[type][i]) continue;
 
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (!isInner(nx, ny) || map[nx][ny] == 1return false;
    }
    return true;
}
 
int movePipe(int x, int y, int type) {
 
    if (x == N - 1 && y == N - 1return 1;
 
    int& ret = cache[x][y][type];
    if (ret != -1return ret;
 
    ret = 0;
    for (int i = 0; i < 3; i++) {
        if (connect[type][i] && canMove(x, y, i)) {
            ret += movePipe(x + dx[i], y + dy[i], i);
        }
    }
    return ret;
}
 
void solution() {
    answer = movePipe(010);
}
 
int main() {
    //초기화
    N = 0;
    memset(map, 0sizeof(map));
    memset(cache, -1sizeof(cache));
    answer = 0;
 
    //입력
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> map[i][j];
        }
    }
 
    //해법
    solution();
 
    //출력
    cout << answer << "\n";
 
    //종료
    return 0;
}

 

백트래킹과 DP에 대해 알아볼 수 있는 문제였습니다.

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

 

16637번: 괄호 추가하기

길이가 N인 수식이 있다. 수식은 0보다 크거나 같고, 9보다 작거나 같은 정수와 연산자(+, -, ×)로 이루어져 있다. 연산자 우선순위는 모두 동일하기 때문에, 수식을 계산할 때는 왼쪽에서부터 순

www.acmicpc.net

<풀이>

1. 수식을 입력받는다.

2. 괄호를 적절히 추가해서 얻을 수 있는 결과의 최대값을 출력한다.

 

<해법>

1. 알고리즘 선택하기

=> 모든 경우의 수를 다 해보아야 합니다. 따라서, 저는 브루트포스를 선택하였습니다.

 

2. 괄호 추가하기

=> 모든 숫자에서 괄호를 추가하는 경우와 안하는 경우로 나누어집니다. 3 + 8 * 7 - 9 * 2 를 예시로 들어보겠습니다. 8에서 괄호를 추가 안하는 경우는 전 숫자에 +8을 하고 다음 숫자 7로 넘어갑니다. 괄호를 추가하는 경우는 전 숫자에 +(8*7)을 하고 다음 숫자 9로 넘어갑니다. 위 방식이 반복적으로 일어나므로, 저는 재귀함수를 이용하여 구현하였습니다. 

 

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
#include <iostream>
#include <string.h>
#include <limits.h>
#include <algorithm>
 
using namespace std;
 
int N;
int nCnt, oCnt;
int num[11];
char oper[10];
int answer;
 
int calculate(int n1, int n2, char oper) {
    switch (oper) {
    case '+':
        return n1 + n2;
    case '-':
        return n1 - n2;
    case '*':
        return n1 * n2;
    }
}
 
int findMaxValue(int idx, int sum) {
 
    if (idx >= nCnt) {
        return sum;
    }
 
    int ret = INT_MIN;
    int nSum = 0;
 
    //괄호 X
    nSum = calculate(sum, num[idx], oper[idx - 1]);
    ret = max(ret, findMaxValue(idx + 1, nSum));
    //괄호 O
    if (idx + 1 < nCnt) {
        nSum = calculate(sum, calculate(num[idx], num[idx + 1], oper[idx]), oper[idx - 1]);
        ret = max(ret, findMaxValue(idx + 2, nSum));
    }
 
    return ret;
}
 
void solution() {
    answer = findMaxValue(10);
}
 
int main() {
    //초기화
    N = 0;
    nCnt = 1, oCnt = 1;
    memset(num, 0sizeof(num));
    memset(oper, '+'sizeof(oper)); //시작할때 '0 +'로 시작하기 위해
    answer = 0;
 
    //입력
    cin >> N;
    for (int i = 0; i < N; i++) {
        char c;
        cin >> c;
        if (i % 2 == 0) num[nCnt++= c - '0';
        else oper[oCnt++= c;
    }
 
    //해법
    solution();
 
    //출력
    cout << answer << "\n";
 
    //종료
    return 0;
}

 

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

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

 

13460번: 구슬 탈출 2

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'

www.acmicpc.net

<풀이>

1. 보드 상태를 입력받는다.

2. 빨간 구슬을 뺄 수 있는 최소 움직임을 출력한다.

 

<해법>

1. 알고리즘 선택하기

=> 모든 경우를 다 해보지 않고서는 풀 수 없습니다. 저는 문제를 읽고 모든 경우를 다 해보는 브루트포스를 선택하였습니다.

 

2. 중복된 탐색 줄이기

=> 모든 경우를 다 해볼경우 중복된 경우가 많이 나올 수 있습니다. 예를 들어, 오른쪽 왼쪽을 반복하는 경우가 있습니다. 저는 중복된 경우를 줄이기 위해서, 빨간공과 파란공의 좌표의 조합으로 방문배열(visited[redX][redY][blueX][blueY])을 반들었습니다. 이렇게 하면 전에 탐색했던 빨간공과 파란공 좌표는 탐색하지 않으므로 중복을 줄일 수 있습니다.

 

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <string.h>
#include <algorithm>
#define INF 987654321
 
using namespace std;
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
int N, M;
char map[10][10];
bool visited[10][10][10][10];
int rX, rY, bX, bY;
int answer;
 
bool isExit(int x, int y) {
    if (map[x][y] == 'O'return true;
    return false;
}
 
bool isSamePosition(int x1, int y1, int x2, int y2) {
    if (x1 == x2 && y1 == y2) return true;
    return false;
}
 
void roll(int& x, int& y, int& dir, int& distance, bool& exit) {
    while (map[x+dx[dir]][y+dy[dir]] != '#') {
        x += dx[dir];
        y += dy[dir];
        distance++;
        if (map[x][y] == 'O') {
            exit = true;
            break;
        }
    }
}
 
int simulation(int rx, int ry, int bx, int by, int cnt) {
 
    if (cnt > 10return INF;
 
    if (isExit(rx, ry) || isExit(bx, by)) {
        if (isExit(bx, by)) return INF;
        return 0;
    }
 
    int ret = INF;
 
    for (int i = 0; i < 4; i++) {
        int nrx = rx, nry = ry, nbx = bx, nby = by;
        int rd = 0, bd = 0;
        bool re = false, be = false;
 
        roll(nrx, nry, i, rd, re);
        roll(nbx, nby, i, bd, be);
 
        //둘 중 하나라도 탈출한 경우
        if (re || be) {
            ret = min(ret, simulation(nrx, nry, nbx, nby, cnt + 1+ 1);
        }
        else {
            //구슬 순서 정리
            if (isSamePosition(nrx, nry, nbx, nby)) {
                if (rd > bd) nrx -= dx[i], nry -= dy[i];
                else nbx -= dx[i], nby -= dy[i];
            }
 
            if (!visited[nrx][nry][nbx][nby]) {
                visited[nrx][nry][nbx][nby] = true;
                ret = min(ret, simulation(nrx, nry, nbx, nby, cnt + 1+ 1);
                visited[nrx][nry][nbx][nby] = false;
            }
        }
    }
 
    return ret;
}
 
void solution() {
    visited[rX][rY][bX][bY] = true;
    answer = simulation(rX, rY, bX, bY, 0);
    visited[rX][rY][bX][bY] = false;
    answer = (answer == INF) ? -1 : answer;
}
 
int main() {
    //초기화
    N = 0, M = 0;
    memset(map, '0'sizeof(map));
    memset(visited, falsesizeof(visited));
    rX = 0, rY = 0, bX = 0, bY = 0;
    answer = 0;
 
    //입력
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> map[i][j];
            if (map[i][j] == 'R') {
                map[i][j] = '.';
                rX = i, rY = j;
            }
            else if (map[i][j] == 'B') {
                map[i][j] = '.';
                bX = i, bY = j;
            }
        }
    }
 
    //해법
    solution();
 
    //출력
    cout << answer << "\n";
 
    //종료
    return 0;
}

 

DFS와 구현에 대해 알아볼 수 있는 문제였습니다.

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 미로를 입력받는다.

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

 

<해법>

1. 알고리즘 선택하기

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

 

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
#include <iostream>
#include <string.h>
 
using namespace std;
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
int trash;
char map[16][16];
bool visited[16][16];
int startX, startY, endX, endY;
bool answer;
 
bool isInner(int x, int y) {
    if (x < 0 || y < 0 || x >= 16 || y >= 16return false;
    return true;
}
 
bool canExit(int x, int y) {
 
    if (x == endX && y == endY) return true;
 
    bool ret = false;
 
    visited[x][y] = true;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
 
        if (!isInner(nx, ny) || visited[nx][ny] || map[nx][ny] == '1'continue;
        
        ret |= canExit(nx, ny);
    }
    return ret;
}
 
void solution() {
    answer = canExit(startX, startY);
}
 
int main() {
    int test_case;
    int T;
 
    T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        trash = 0;
        memset(map, 0sizeof(map));
        memset(visited, falsesizeof(visited));
        startX = 0, startY = 0, endX = 0, endY = 0;
        answer = false;
 
        //입력
        cin >> trash;
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 16; j++) {
                cin >> map[i][j];
                if (map[i][j] == '2') {
                    startX = i, startY = j;
                }
                else if (map[i][j] == '3') {
                    endX = i, endY = j;
                }
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

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

[C++] SWEA 1225 - 암호생성기  (0) 2022.12.24
[C++] SWEA 5650 - 핀볼 게임(2)  (0) 2022.12.23
[C++] SWEA 1224 - 계산기3  (0) 2022.12.21
[C++] SWEA 1219 - 길찾기(2)  (0) 2022.12.21
[C++] SWEA 1218 - 괄호 짝짓기  (0) 2022.12.21

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

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
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
#include <iostream>
#include <stack>
 
using namespace std;
 
int length;
string str;
int answer;
 
int priority(char c) {
    if (c == '(' || c == ')'return 0//스택 안에 있는 괄호는 우선순위가 가장 낮음
    else if (c == '+' || c == '-'return 1;
    else if (c == '*' || c == '/'return 2;
}
 
//중위표기식 -> 후위표기식
string convert() {
    string output = "";
    stack<char> s;
    for (int i = 0; i < length; i++) {
        char c = str[i];
 
        //숫자
        if (0 <= 'c' && c >= '9') {
            output += c;
        }
        //그 외
        else {
            //괄호
            if (c == '(' || c == ')') {
                if (c == '(') s.push('(');
                else {
                    while (!s.empty() && s.top() != '(') {
                        output += s.top();
                        s.pop();
                    }
                    s.pop();
                }
            }
            //비괄호
            else {
                while (!s.empty() && priority(s.top()) >= priority(c)) {
                    output += s.top();
                    s.pop();
                }
                s.push(c);
            }
        }
    }
 
    while (!s.empty()) {
        output += s.top();
        s.pop();
    }
 
    return output;
}
 
//후위표기식 계산
int calculate(string str) {
    int output = 0;
    stack<int> num;
    for (int i = 0; i < str.length(); i++) {
        char c = str[i];
 
        if ('0' <= c && c <= '9') num.push(c - '0');
        else {
            int num1 = num.top();
            num.pop();
            int num2 = num.top();
            num.pop();
            switch (c) {
            case '+':
                num.push(num1 + num2);
                break;
            case '-':
                num.push(num1 - num2);
                break;
            case '*':
                num.push(num1 * num2);
                break;
            case '/':
                num.push(num1 / num2);
                break;
            }
        }
    }
 
    output = num.top();
    return output;
}
 
void solution() {
    string convertStr = convert();
    answer = calculate(convertStr);
}
 
int main() {
    int test_case;
    int T;
 
    T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        length = 0;
        str = "";
        answer = 0;
 
        //입력
        cin >> length >> str;
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

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

[C++] SWEA 5650 - 핀볼 게임(2)  (0) 2022.12.23
[C++] SWEA 1226 - 미로1  (0) 2022.12.21
[C++] SWEA 1219 - 길찾기(2)  (0) 2022.12.21
[C++] SWEA 1218 - 괄호 짝짓기  (0) 2022.12.21
[C++] SWEA 2117 - 홈 방범 서비스(2)  (1) 2022.12.21

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

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 길 정보가 주어진다.

2. 출발점(0)에서 도착점(99)로 갈 수 있는지 출력한다.

 

<해법>

1. 알고리즘 선택하기

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

 

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
#include <iostream>
#include <string.h>
 
using namespace std;
 
int trash;
int cnt;
int map[100][2];
bool visited[100];
bool answer;
 
bool canGo(int node) {
    if (node == 99return true;
 
    bool ret = false;
    visited[node] = true;
    for (int i = 0; i < 2; i++) {
        int nxt = map[node][i];
        if (nxt != -1 && !visited[nxt]) {
            ret |= canGo(nxt);
        }
    }
    return ret;
}
 
void solution() {
    answer = canGo(0);
}
 
int main() {
    int test_case;
    int T;
 
    T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        trash = 0;
        cnt = 0;
        memset(map, -1sizeof(map));
        memset(visited, falsesizeof(visited));
        answer = false;
 
        //입력
        cin >> trash >> cnt;
        for (int i = 0; i < cnt; i++) {
            int from = 0, to = 0;
            cin >> from >> to;
            if (map[from][0== -1) map[from][0= to;
            else map[from][1= to;
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

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

[C++] SWEA 1226 - 미로1  (0) 2022.12.21
[C++] SWEA 1224 - 계산기3  (0) 2022.12.21
[C++] SWEA 1218 - 괄호 짝짓기  (0) 2022.12.21
[C++] SWEA 2117 - 홈 방범 서비스(2)  (1) 2022.12.21
[C++] SWEA 1217 - 거듭 제곱  (0) 2022.12.21

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 괄호 문자열을 입력받는다.

2. 괄호들의 짝이 모두 맞는지 출력한다.

 

<해법>

1. 괄호들이 짝이 맞는지 판단하는 방법

=> 스택을 사용합니다. '({[' 이렇게 나왔다면, 뒤에는 ']})' 이렇게 나와야합니다. 따라서, 스택의 연산(push, pop)으로 자연스럽게 괄호의 짝을 알아볼 수 있습니다.

 

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
#include <iostream>
#include <stack>
 
using namespace std;
 
int length;
string str;
bool answer;
 
bool isPair(char left, char right) {
    if (left == '(' && right == ')'return true;
    else if (left == '[' && right == ']'return true;
    else if (left == '{' && right == '}'return true;
    else if (left == '<' && right == '>'return true;
    return false;
}
 
bool isValid(string str) {
    stack<char> s;
    for (int i = 0; i < length; i++) {
        char c = str[i];
        if (c == '(' || c == '[' || c == '{' || c == '<') {
            s.push(c);
        }
        else {
            if (isPair(s.top(), c)) s.pop();
            else return false;
        }
    }
    if (!s.empty()) return false;
    return true;
}
 
void solution() {
    answer = isValid(str);
}
 
int main() {
    int test_case;
    int T;
 
    T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        length = 0;
        str = "";
        answer = false;
 
        //입력
        cin >> length >> str;
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

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

[C++] SWEA 1224 - 계산기3  (0) 2022.12.21
[C++] SWEA 1219 - 길찾기(2)  (0) 2022.12.21
[C++] SWEA 2117 - 홈 방범 서비스(2)  (1) 2022.12.21
[C++] SWEA 1217 - 거듭 제곱  (0) 2022.12.21
[C++] SWEA 1216 - 회문2  (0) 2022.12.15

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

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 도시 정보를 입력받는다.

2. 손해를 보지 않으면서 가장 많은 집들에게 서비스를 제공할 수 있는 영역을 찾고, 그 때 서비스를 받는 집들의 수를 출력한다.

 

<해법>

1. 마름모 서비스 영역을 찾는 방법

=> 저는 마름모 모양으로 커지는 모습이 BFS가 탐색하는 모습과 유사하다고 생각하여서, BFS를 이용하여 단계별로 탐색하였습니다.

 

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 <string.h>
#include <algorithm>
#include <queue>
 
using namespace std;
 
struct pos {
    int x, y;
};
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
int N, M;
int map[20][20];
bool visited[20][20];
int answer;
 
bool isInner(pos p) {
    if (p.x < 0 || p.y < 0 || p.x >= N || p.y >= N) return false;
    return true;
}
 
int findServiceArea(pos p) {
    queue<pos> q;
    bool visited[20][20];
    memset(visited, falsesizeof(visited));
 
    q.push(p);
    visited[p.x][p.y] = true;
    int k = 1;
    int people = 0;
    int output = 0;
 
    while (!q.empty()) {
        int qsize = q.size();
        while (qsize--) {
            pos cur = q.front();
            q.pop();
 
            if (map[cur.x][cur.y] == 1) people++;
 
            for (int i = 0; i < 4; i++) {
                pos nxt = cur;
                nxt.x += dx[i];
                nxt.y += dy[i];
 
                if (!isInner(nxt) || visited[nxt.x][nxt.y]) continue;
 
                q.push(nxt);
                visited[nxt.x][nxt.y] = true;
            }
        }
 
        int cost = k * k + (k - 1* (k - 1);
        if (people * M >= cost) output = people;
        k++;
    }
 
    return output;
}
 
void solution() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            answer = max(answer, findServiceArea({ i, j }));
        }
    }
}
 
int main() {
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0, M = 0;
        memset(map, 0sizeof(map));
        answer = 0;
 
        //입력
        cin >> N >> M;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cin >> map[i][j];
            }
        }
 
        //해법
        solution();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

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

[C++] SWEA 1219 - 길찾기(2)  (0) 2022.12.21
[C++] SWEA 1218 - 괄호 짝짓기  (0) 2022.12.21
[C++] SWEA 1217 - 거듭 제곱  (0) 2022.12.21
[C++] SWEA 1216 - 회문2  (0) 2022.12.15
[C++] SWEA 1215 - 회문1(2)  (0) 2022.12.15

+ Recent posts