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

 

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
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
using namespace std;
 
//북,동,남,서
int di[] = { -1,0,1,0 };
int dj[] = { 0,1,0,-1 };
 
//방향 반대로 바꾸기
int reverseDir[] = { 2,3,0,1 };
 
//블록만날때 바뀌는 방향 index
int block[6][4= {
    {0,0,0,0},
    {2,3,1,0}, //1번 블록
    {1,3,0,2}, //2번 블록
    {3,2,0,1}, //3번 블록
    {2,0,3,1}, //4번 블록
    {2,3,0,1}  //5번 블록
};
 
int N;
int map[102][102];
int res;
 
int gameStart(int startX, int startY, int startDir) {
 
    //점수
    int score = 0;
 
    //위치
    int x = startX, y = startY, dir = startDir;
 
    //시뮬레이션
    while (true) {
 
        x += di[dir], y += dj[dir];
 
        //5가지 경우(빈칸,블랙홀,벽,블록,웜홀)
 
        //1.빈칸일 경우
        if (map[x][y] == 0) {
            //시작지점으로 돌아왔을 경우 -> 종료
            if (x == startX && y == startY) {
                return score;
            }
        }
 
        //2.블랙홀일 경우 -> 종료
        else if (map[x][y] == -1) {
            return score;
        }
 
        //3.벽일 경우
        else if (map[x][y] == -2) {
            //방향 반대 전환
            dir = reverseDir[dir];
            score++;
        }
 
        //4.블록일 경우
        else if (map[x][y] >= 1 && map[x][y] <= 5) {
            //방향 전환
            dir = block[map[x][y]][dir];
            score++;
        }
 
        //5.웜홀일 경우
        else {
            //위치 변환
            bool isChanged = false;
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= N; j++) {
                    //맵 위의 값이 같고, 좌표가 다를 경우 -> 다른 웜홀 발견
                    if ((map[i][j] == map[x][y]) && !(x == i && y == j)) {
                        x = i, y = j;
                        isChanged = true;
                        break;
                    }
                }
                if (isChanged) {
                    break;
                }
            }
        }
    }
}
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        for (int i = 0; i < 102; i++) {
            for (int j = 0; j < 102; j++) {
                map[i][j] = -2;
            }
        }
        res = 0;
 
        //입력
        cin >> N;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
                cin >> map[i][j];
            }
        }
 
        //핀볼 게임판 전체 탐색
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
 
                //빈칸인 곳에서 핀볼 게임 시작
                if (map[i][j] == 0) {
                    //4방향 모두 굴리기
                    for (int k = 0; k < 4; k++) {
                        //gameStart(x좌표, y좌표, 방향)
                        if (gameStart(i, j, k) > res) {
                            res = gameStart(i, j, k);
                        }
                    }
                }
            }
        }
 
        //출력
        cout << "#" << test_case << " " << res << "\n";
    }
    return 0;
}
 

 

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

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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 사용자 A, B의 좌표를 한번씩 이동시킨다.

2. 이동할 때 마다 사용자들과 모든 BC의 거리를 계산 후, 사용 가능한 BC의 정보를 각각 벡터에 저장한다.

3. A와 B가 사용할 모든 BC의 경우를 판단하여, 가장 큰 충전량의 합을 계산한다.

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
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
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
 
//구조체 : BC 정보
struct BC {
    int x, y;
    int c;
    int p;
};
 
//5방향
int di[] = { 0,-1,0,1,0 };
int dj[] = { 0,0,1,0,-1 };
 
int M, BC_cnt;
int A[101];
int B[101];
vector<BC> bc;
int res;
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        memset(A, 0sizeof(A));
        memset(B, 0sizeof(B));
        bc.clear();
        res = 0;
 
        //입력
        cin >> M >> BC_cnt;
        for (int i = 1; i <= M; i++) {
            cin >> A[i];
        }
        for (int i = 1; i <= M; i++) {
            cin >> B[i];
        }
        for (int i = 0; i < BC_cnt; i++) {
            int x, y, c, p;
            cin >> y >> x >> c >> p;
            bc.push_back({ x,y,c,p });
        }
 
        //A가 사용할 수 있는 BC, B가 사용할 수 있는 BC 저장 벡터
        vector<int> a_BC, b_BC;
 
        //A,B 초기 좌표
        int ax = 1, ay = 1, bx = 10, by = 10;
 
        //시간마다 탐색
        for (int i = 0; i <= M; i++) {
 
            a_BC.clear();
            b_BC.clear();
 
            //A좌표, B좌표
            ax += di[A[i]];
            ay += dj[A[i]];
            bx += di[B[i]];
            by += dj[B[i]];
 
            //모든 BC와 거리 구하기
            for (int j = 0; j < BC_cnt; j++) {
                int a_dist = abs(ax - bc[j].x) + abs(ay - bc[j].y);
                int b_dist = abs(bx - bc[j].x) + abs(by - bc[j].y);
 
                //사용할 수 있는 거리라면 벡터에 저장
                if (a_dist <= bc[j].c) {
                    a_BC.push_back(j);
                }
                if (b_dist <= bc[j].c) {
                    b_BC.push_back(j);
                }
            }
 
            //A와 B가 모두 사용할 수 있는 BC가 있는 경우(BC가 겹치는 경우 처리)
            if (!a_BC.empty() && !b_BC.empty()) {
 
                //두 개의 합 중 가장 큰 값 구해서 더해주기
                int maxSum = 0;
                for (int k = 0; k < a_BC.size(); k++) {
                    for (int l = 0; l < b_BC.size(); l++) {
 
                        int tmpA = bc[a_BC[k]].p;
                        int tmpB = bc[b_BC[l]].p;
 
                        if (a_BC[k] == b_BC[l]) {
                            tmpA /= 2;
                            tmpB /= 2;
                        }
 
                        int tmpSum = tmpA + tmpB;
                        if (tmpSum > maxSum) {
                            maxSum = tmpSum;
                        }
                    }
                }
                res += maxSum;
            }
            //A만 사용할 수 있는 BC가 있는 경우
            else if (!a_BC.empty()) {
                //A가 사용할 수 있는 최대값 구해서 더해주기
                int maxA = 0;
                for (int k = 0; k < a_BC.size(); k++) {
                    if (bc[a_BC[k]].p > maxA) {
                        maxA = bc[a_BC[k]].p;
                    }
                }
                res += maxA;
            }
            //B만 사용할 수 있는 BC가 있는 경우
            else if (!b_BC.empty()) {
                //B가 사용할 수 있는 최대값 구해서 더해주기
                int maxB = 0;
                for (int k = 0; k < b_BC.size(); k++) {
                    if (bc[b_BC[k]].p > maxB) {
                        maxB = bc[b_BC[k]].p;
                    }
                }
                res += maxB;
            }
        }
 
        //결과 출력
        cout << "#" << test_case << " " << res << "\n";
    }
    return 0;
}
 

 

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

https://programmers.co.kr/learn/courses/30/lessons/42890

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

1. 가능한 모든 후보키를 계산합니다.

2. 유일성과 최소성을 확인하여 가능한 후보키만을 결과값으로 저장합니다.

3. 결과를 출력합니다.

 

<해법>

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
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
 
int col, row;
vector<vector<string>> r;
vector<int> v;
vector<vector<int>> key;
 
void go(int index, int cnt) {
 
    //원하는 개수를 다 뽑았으면
    if (cnt == 0) {
        
        //최소성 확인 - 후보키에 이미 같은 조합이 있는지 확인
        if (!key.empty()) {
            for (int i = 0; i < key.size(); i++) {
 
                bool isMinimal = false;
 
                //후보키 안에 모두 같은 속성이 있을 시 minimal X
                //-> 후보키 안에 하나라도 다른 속성이 있으면 OK
                for (int j = 0; j < key[i].size(); j++) {
                    bool alreadyIn = false;
                    for (int k = 0; k < v.size(); k++) {
                        if (key[i][j] == v[k]) {
                            alreadyIn = true;
                        }
                    }
                    if (!alreadyIn) {
                        isMinimal = true;
                    }
                }
                
                if (!isMinimal) {
                    return;
                }
            }
        }
        
        //유일성 확인 - 모든 튜플을 식별할 수 있는지 확인
        vector<string> cmp;
        bool isUnique = true;
 
        //후보키로 문자열 만들기
        for (int i = 0; i < row; i++) {
            string s = "";
            for (int j = 0; j < v.size(); j++) {
                s += r[i][v[j]];
            }
            cmp.push_back(s);
        }
 
        sort(cmp.begin(), cmp.end());
        
        //문자열 중 같은 것이 있다면 -> 식별X
        for (int i = 0; i < row - 1; i++) {
            if (cmp[i] == cmp[i + 1]) {
                isUnique = false;
            }
        }
 
        //최종적으로 가능한 후보키 저장
        if (isUnique) {
            key.push_back(v);
        }
 
        return;
    }
 
    //갯수만큼 저장
    for (int i = index; i < col; i++) {
        v.push_back(i);
        go(i + 1, cnt - 1);
        v.pop_back();
    }
 
    return;
}
 
int solution(vector<vector<string>> relation) {
    int answer = 0;
 
    //전역변수에 값 저장
    r = relation;
    col = relation[0].size();
    row = relation.size();
 
    //1,2.. 개씩 뽑기
    for (int i = 1; i <= col; i++) {
        go(0, i);
    }
 
    //결과 저장
    answer = key.size();
 
    return answer;
}
 

 

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

https://programmers.co.kr/learn/courses/30/lessons/42889

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

1. 주어진 입력으로 실패율을 구하는데 필요한 분모와 분자를 구한다.

2. 스테이지의 번호와 실패율을 벡터에 저장한다.

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
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
 
bool cmp(pair<int,double> a, pair<int,double> b) {
 
    //실패율이 같을 경우, 스테이지 번호가 낮은 순으로 정렬
    if (a.second == b.second) {
        return a.first < b.first;
    }
    else {
        return a.second > b.second;
    }
}
 
vector<int> solution(int N, vector<int> stages) {
    vector<int> answer;
 
    int bunJa[502];
    int bunMo[502];
    memset(bunJa, 0sizeof(bunJa));
    memset(bunMo, 0sizeof(bunMo));
 
    //vector<스테이지 번호, 실패율>
    vector<pair<int,double>> rate;
 
    //각각 스테이지 실패율의 분모, 분자 구하기
    for (int i = 0; i < stages.size(); i++) {
        for (int j = 1; j <= stages[i]; j++) {
            bunMo[j]++;
        }
        bunJa[stages[i]]++;
    }
 
    //실패율 구하기
    for (int i = 1; i <= N; i++) {
        if (bunMo[i] == 0) {
            rate.push_back({ i,0 });
        }
        else {
            rate.push_back({ i,double(bunJa[i]) / double(bunMo[i]) });
        }
    }
 
    //실패율 정렬 
    sort(rate.begin(), rate.end(), cmp);
 
    //결과 저장
    for (int i = 0; i < N; i++) {
        answer.push_back(rate[i].first);
    }
 
    return answer;
}
 

 

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

https://programmers.co.kr/learn/courses/30/lessons/64064

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

1. 제재 아이디가 가능한 모든 경우를 계산한다.

2. 중복되는 제재 아이디 경우를 제외합니다.

3. 모든 경우의 수를 출력합니다.

 

<해법>

1. 제재 아이디가 가능한 모든 경우를 계산하는 방법.

=> 모든 경우를 시뮬레이션 하는 대표적인 방법으로 '백트래킹'이 있습니다. 위 문제에서 저는 '백트래킹'을 재귀함수로 구현하였습니다. 저는 재귀함수로 구현하기 이전에 아래와 같은 그림으로 대표적인 틀을 잡습니다.

 

2. 중복되는 경우를 제외하는 방법.

=> 위 문제에서 중복되는 경우는 두 가지가 있습니다. 아이디가 중복되서는 안되며, 나열된 아이디 내용들이 중복되서는 안됩니다. 

(1) 아이디 중복 제외

저는 방문 배열을 이용하여 이전 단계에서 제재 아이디로 탐색된 경우, 탐색을 할 수 없도록 하였습니다.

(2) 나열된 아이디 내용들 중복 제외

저는 자료구조 'set'를 사용하였습니다. 'set'를 이용하여 중복된 내용이 담겼을 경우 제외되도록 하였습니다.

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>
#include <vector>
#include <set>
using namespace std;
 
vector<string> user;
vector<string> banned;
bool visited[10];
set<string> s;
 
void go(int index) {
 
    //종료조건 : 모든 불량 사용자 아이디 탐색 완료
    if (index == banned.size()) {
 
        //제재 아이디로 등록된 아이디 한 문자열로 만들기
        string tmp = "";
        for (int i = 0; i < user.size(); i++) {
            if (visited[i]) {
                tmp += user[i];
            }
        }
 
        //세트로 중복 제거
        s.insert(tmp);
        return;
    }
 
    //불량 사용자 아이디 마다 가능한 제재 아이디 탐색
    for (int i = 0; i < user.size(); i++) {
 
        bool isAble = true;
        
        //이전 탐색에서 제재 아이디로 등록된 경우 -> 불가능
        if (visited[i]) {
            continue;
        }
 
        //아이디 길이가 다를 경우 -> 불가능
        if (user[i].length() != banned[index].length()) {
            continue;
        }
 
        //각 문자 비교 탐색
        for (int j = 0; j < user[i].length(); j++) {
            if (banned[index][j] == '*') {
                continue;
            }
            //문자가 다를경우 -> 불가능
            if (banned[index][j] != user[i][j]) {
                isAble = false;
                break;
            }
        }
 
        //제재 아이디가 가능한 경우 -> 다음 단계
        if (isAble) {
            visited[i] = true;
            go(index + 1);
            visited[i] = false;
        }
    }
    return;
}
 
int solution(vector<string> user_id, vector<string> banned_id) {
    int answer = 0;
 
    user = user_id;
    banned = banned_id;
 
    //재귀함수 시작
    go(0);
 
    //결과 저장
    answer = s.size();
 
    return answer;
}
 

 

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

https://programmers.co.kr/learn/courses/30/lessons/42888

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

1. 주어진 명령(문자열)을 해독하여 각각 유저 아이디와 닉네임을 매칭한다.

2. 명령에 맞는 출력물을 결과에 저장한다.

<해법>

1. 문자열을 해독하는 방법.

=> 각 문자열은 공백으로 구분되어 있다고 합니다. 그렇다면, 문자열에서 공백까지 문자는 각각의 정보를 담고있다고 해석할 수 있습니다.

예를들어 "Enter uid1234 Muzi"의 문자열을 탐색할 때, 앞에서부터 공백이 나오기 전까지 한 문자씩 검사합니다.

E -> n -> t -> e -> r -> ' ' // 공백 발견

공백을 발견하였을 시 그 전까지 문자들 Enter을 저장합니다.

위와 같은 수행을 반복하면 Enter, uid1234, Muzi를 나눌 수 있습니다.

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
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
 
struct message {
    string cmd;
    string user_id;
};
 
vector<string> solution(vector<string> record) {
 
    vector<string> answer;
 
    map<stringstring> user;
    vector<message> v;
 
    for (int i = 0; i < record.size(); i++) {
 
        //문자열 분리
        //tmpV[0] : Enter or Leave or tmpV, tmpV[1] : uidXXXX, tmpV[2] : nickname
        vector<string> tmpV;
        string tmp = "";
        for (int j = 0; j < record[i].length(); j++) {
            if (record[i][j] == ' ') {
                tmpV.push_back(tmp);
                tmp = "";
            }
            else {
                tmp += record[i][j];
            }
        }
        tmpV.push_back(tmp);
 
        //명령 수행
        if (tmpV[0== "Enter") {
            user[tmpV[1]] = tmpV[2];
            v.push_back({ "Enter",tmpV[1] });
        }
        else if (tmpV[0== "Leave") {
            v.push_back({ "Leave", tmpV[1] });
        }
        else {
            user[tmpV[1]] = tmpV[2];
        }
    }
 
    //결과값 저장
    for (int i = 0; i < v.size(); i++) {
        if (v[i].cmd == "Enter") {
            answer.push_back(user[v[i].user_id] + "님이 들어왔습니다.");
        }
        else {
            answer.push_back(user[v[i].user_id] + "님이 나갔습니다.");
        }
    }
    return answer;
}
 

 

문자열 파싱에 대해 알아볼 수 있는 문제였습니다.

https://programmers.co.kr/learn/courses/30/lessons/64065

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

1. 주어진 문자열을 잘 쪼개어서 각각 그룹으로 만든다.

2. 그룹의 크기가 가장 작은 것부터 겹쳐지지 않은 원소들을 결과 벡터에 저장한다.

<해법>

1. 문자열을 쪼개어서 그룹화 시키는 방법.

=> 문자열의 처음과 끝의 '{', '}'은 필요가 없으므로 제외하였습니다. 제외하면 {1,2,3},{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 <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
bool visited[100001];
 
bool cmp(vector<int> o1, vector<int> o2) {
    return o1.size() < o2.size();
}
 
vector<int> solution(string s) {
    
    vector<int> answer;
 
    //그룹화된 숫자들 저장
    vector<vector<int>> grp;
 
    int m = s.length();
 
    //시작과 끝의 '{','}' 필요 X
    int index = 1;
 
    while (true) {
 
        //종료조건
        if (index == m - 1) {
            break;
        }
 
        //'{'부터 그룹
        if (s[index] == '{') {
 
            vector<int> v;
            string tmp = "";
            int tmpInt;
 
            index++;
 
            while (true) {
 
                //'}'까지 그룹 
                if (s[index] == '}') {
                    tmpInt = stoi(tmp);
                    v.push_back(tmpInt);
                    break;
                }
 
                //','까지 숫자변환 후 저장
                if (s[index] == ',') {
                    tmpInt = stoi(tmp);
                    v.push_back(tmpInt);
                    tmp = "";
                }
                //숫자 저장
                else {
                    tmp += s[index];
                }
 
                index++;
            }
            //'{  }'안에 있던 원소들 그룹화해서 담아주기
            grp.push_back(v);
        }
        index++;
    }
 
    //그룹의 크기에 따라 정렬
    sort(grp.begin(), grp.end(), cmp);
 
    //answer에 겹치지 않은 원소들 넣어주기
    for (int i = 0; i < grp.size(); i++) {
        for (int j = 0; j < grp[i].size(); j++) {
            if (!visited[grp[i][j]]) {
                visited[grp[i][j]] = true;
                answer.push_back(grp[i][j]);
            }
        }
    }
    return answer;
}
 

 

문자열 파싱에 대해 알아볼 수 있는 문제였습니다.

https://programmers.co.kr/learn/courses/30/lessons/64061

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

<풀이>

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
#include <iostream>
#include <vector>
#include <cstring>
#include <stack>
using namespace std;
 
int map[31][31];
stack<int> basket;
 
int solution(vector<vector<int>> board, vector<int> moves) {
 
    int answer = 0;
    
    memset(map, 0sizeof(map));
 
    int m = board.size();
    int n = moves.size();
 
    //보드 -> 맵
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
            map[i][j] = board[i][j];
        }
    }
 
    //뽑기 명령 수행
    for (int i = 0; i < n; i++) {
 
        //명령의 열 선택
        int line = moves[i] - 1;
 
        //열의 가장 위에서부터 아래로 탐색
        for (int j = 0; j < m; j++) {
            
            //인형을 발견하였을 경우, 인형 뽑기
            if (map[j][line] != 0) {
 
                //바구니가 비어있으면 인형 담기
                if (basket.empty()) {
                    basket.push(map[j][line]);
                }
                //바구니가 비어있지 않을 경우
                else {
                    //뽑은 인형과 바구니 제일 위의 인형이 같을 경우 없애주고, answer+2
                    if (map[j][line] == basket.top()) {
                        basket.pop();
                        answer += 2;
                    }
                    //같지 않다면 바구니에 담기
                    else {
                        basket.push(map[j][line]);
                    }
                }
 
                //맵에서 인형 없애기
                map[j][line] = 0;
                break;
            }
        }
    }
    return answer;
}
 

 

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

+ Recent posts