문제 해설

 

 스택을 이용해서 주어진 수열을 출력할 수 있는가에 대한 문제입니다. 스택의 경우 LIFO 구조를 가지고 있으므로, 순서에 유의하여야 합니다. 예시로 주어진 "5->3->4" 의 경우, 5를 출력하고 나면 스택에 남은 숫자는 {3, 4}입니다. 이 때, 나올 수 있는 수는 더 늦게 스택에 push된 4이므로 4보다 3을 먼저 출력할 수 없습니다. 따라서 NO를 출력해야 합니다. 이후의 설명은 코드를 첨부하도록 하겠습니다.

 

 

코드

 

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
#include <iostream>
#include <stack>
#include <vector>
#include <cstring>
 
using namespace std;
 
bool isUse[100001];
 
int main() {
 
    int n, now = 0;
    cin >> n;
 
    memset(isUse, falsesizeof(isUse));
 
    //stack을 만든다.
    stack <int> s;
    vector <char> output;
    bool isTrue = true;
 
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
 
        if (now < x) { // 만약 현재 위치보다 출력해야 하는 값이 크다면, 스택에 넣어준다.
            for (int i = now + 1; i <= x; i++) {
                if (!isUse[i]) {
                    s.push(i);
                    output.push_back('+');
                    isUse[i] = true;
                }
            }
            now = s.top();
        }
 
        if (now == x) {
            s.pop();
            output.push_back('-');
            if (!s.empty()) {
                now = s.top();
            }
            else {
                now = 0;
            }
        }
        else {
            isTrue = false;
            break;
        }
    }
 
    if (isTrue) {
        for (auto i : output) {
            cout << i << '\n';
        }
    }
    else {
        cout << "NO\n";
    }
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

1874번: 스택 수열

1부터 n까지에 수에 대해 차례로 [push, push, push, push, pop, pop, push, push, pop, push, push, pop, pop, pop, pop, pop] 연산을 수행하면 수열 [4, 3, 6, 8, 7, 5, 2, 1]을 얻을 수 있다.

www.acmicpc.net

 

코드

 

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>
 
using namespace std;
 
int stck[10001];
 
int main() {
 
    string s;
    int n, x;
    int t = -1;    //top index
    cin >> n;
 
    while (n--) {
        cin >> s;
 
        if (s == "push") {
            cin >> x;
            t++;
            stck[t] = x;
        }
        else if (s == "pop") {
            if (t == -1) {
                cout << -1 << '\n';
            }
            else {
                cout << stck[t] << '\n';
                t--;
            }
        }
        else if (s == "size") {
            cout << t + 1 << '\n';
        }
        else if (s == "empty") {
            if (t == -1) {
                cout << 1 << '\n';
            }
            else {
                cout << 0 << '\n';
            }
        }
        else if (s == "top") {
            if (t == -1) {
                cout << -1 << '\n';
            }
            else {
                cout << stck[t] << '\n';
            }
        }
    }
 
    return 0;
}

 

 

제출 결과

 

 

 

문제 출처

 

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

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

www.acmicpc.net

 

'algorithm codes > baekjoon online judge' 카테고리의 다른 글

4307번: 개미  (0) 2019.04.18
1874번: 스택 수열  (0) 2019.04.16
4948번: 베르트랑 공준  (0) 2019.04.15
1929번: 소수 구하기  (0) 2019.04.15
2581번: 소수 (백준 온라인 저지, C++)  (0) 2019.04.15

코드

 

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
#include <iostream>
#include <cstring>
 
using namespace std;
 
bool number[1000001];
 
int main() {
 
    memset(number, truesizeof(number));
 
    number[1= false;
 
    for (int i = 2; i <= 2 * 123456; i++) {
        if (number[i]) {
            for (int j = 2; j <= 2 * 123456 / i; j++) {
                number[j * i] = false;
            }
        }
    }
 
    while (1) {
 
        int n, num = 0;
        cin >> n;
 
        if (n == 0break;
 
        for (int i = n + 1; i <= 2 * n; i++) {
            if (number[i]) {
                num++;
            }
        }
 
        cout << num << '\n';
    }
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

4948번: 베르트랑 공준

문제 베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼프가 1850년에 증명했다. 예를 들어, 10보다 크고, 20보다 작거나 같은 소수는 4개가 있다. (11, 13, 17, 19) 또, 14보다 크고, 28보다 작거나 같은 소수는 3개가 있다. (17,19, 23) n이 주어졌을 때, n보다 크고, 2n보

www.acmicpc.net

 

문제 풀이

 

 에라토스테네스의 체를 활용하여 소수를 구하였습니다.

 

 

코드

 

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
#include <iostream>
#include <cstring>
 
using namespace std;
 
bool number[1000001];
 
int main() {
 
    int m, n;
 
    cin >> m >> n;
 
    memset(number, truesizeof(number));
 
    number[1= false;
 
    for (int i = 2; i <= n; i++) {
        if (number[i]) {
            for (int j = 2; j <= n / i; j++) {
                number[j * i] = false;
            }
        }
    }
 
    for (int i = m; i <= n; i++) {
        if (number[i]) {
            cout << i << ' ';
        }
    }
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

1929번: 소수 구하기

첫째 줄에 자연수 M과 N이 빈 칸을 사이에 두고 주어진다. (1 ≤ M ≤ N ≤ 1,000,000)

www.acmicpc.net

 

문제 해설

 

단순히 소수를 구하면 되는 문제로, 우선 소수를 모두 구해주고 해당 범위 내에 있는 소수를 출력해주었습니다.

 

 

코드

 

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
#include <iostream>
#include <cstring>
 
using namespace std;
 
bool number[10001];
 
int main() {
 
    int m, n;
 
    cin >> m >> n;
 
    int sum = 0;
    int min = -1;
 
    memset(number, truesizeof(number));
 
    number[1= false;
 
    for (int i = 2; i <= n; i++) {
        if (number[i]) {
            for (int j = 2; j <= n / i; j++) {
                number[j * i] = false;
            }
        }
    }
 
    for (int i = m; i <= n; i++) {
        if (number[i]) {
            sum += i;
            if (min == -1) {
                min = i;
            }
        }
    }
 
    if (min == -1) {
        cout << min << '\n';
    }
    else {
        cout << sum << '\n' << min << '\n';
    }
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

채점 결과

 

 

 

 

문제 출처

 

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

 

2581번: 소수

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.  단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.

www.acmicpc.net

 

문제 풀이

 

 문제 해결을 위한 절차는 다음과 같습니다.

1) 궁수의 위치를 정하여 simulation 함수로 넘겨줍니다.

2) 궁수마다 가장 가까운 적의 위치를 중복없이 저장해 줍니다.

3) 사정 거리 내에 들어온다면 적을 없애주고, 적을 한 칸 전진 시킵니다.

4) 남아있는 적이 없다면 simulation을 종료시키고 물리친 적이 가장 많을 때를 저장시켜 줍니다.

 

 

코드

 

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
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <cstring>
 
using namespace std;
 
int n, m, d;
int field[15][15];
 
int dist(int ex, int ey, int ay) {
    return abs(n - ex) + abs(ey - ay);
}
 
int simulation(int a, int b, int c) {
    
    int sum = 0;
    int tmp[15][15];
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            tmp[i][j] = field[i][j];
        }
    }
 
    while (1) {
        vector<int> v = { a, b, c };
        set<pair<intint>> s;
 
        for (auto x : v) { //x = a
            
            int dist_f[15][15];
            int dist_min = -1;
 
            memset(dist_f, -1sizeof(dist_f));
 
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    
                    if (tmp[i][j] == 1) {
                        dist_f[i][j] = dist(i, j, x);
                        if (dist_min == -1 || dist_min > dist_f[i][j]) {
                            dist_min = dist_f[i][j];
                        }
                    }
                }
            }
 
            if (dist_min <= d) {
 
                int ex = -1, ey = -1;
                for (int j = 0; j < m; j++) {
                    for (int i = 0; i < n; i++) {
                        if (dist_min == dist_f[i][j]) {
                            ex = i;
                            ey = j;
                            break;
                        }
                    }
                    if (ey != -1) {
                        break;
                    }
                }
                s.emplace(ex, ey);
            }
        }
        
        for (auto x : s) {
            tmp[x.first][x.second] = 0;
            sum++;
        }
        
        bool isFin = true;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j < m; j++) {
                if(i == 0){
                    tmp[i][j] = 0;
                }
                else{
                    tmp[i][j] = tmp[i - 1][j];
                }
                
                if (tmp[i][j] == 1) {
                    isFin = false;
                }
            }
        }
        if (isFin) return sum;
    }
}
 
int main() {
 
    cin >> n >> m >> d;
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> field[i][j];
        }
    }
 
    vector<int> p(m, 0);
    p[0= 1;
    p[1= 1;
    p[2= 1;
 
    sort(p.begin(), p.end());
 
    int ans = -1;
    do{
        vector<int> v;
 
        for (int i = 0; i < m; i++) {
            if (p[i] == 1) {
                v.push_back(i);
            }
        }
        int sum = simulation(v[0], v[1], v[2]);
 
        if (ans == -1 || sum > ans) {
            ans = sum;
        }
 
    } while (next_permutation(p.begin(), p.end()));
 
    cout << ans << '\n';
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

17135번: 캐슬 디펜스

첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

www.acmicpc.net

 

문제 해설

 

 simulate 함수를 만들어, 같은 울타리 내에 있는 양과 늑대의 수 중 늑대의 수가 양의 수 이상인 경우 양의 수를 0으로 바꾼 후 리턴해주고, 양의 수가 늑대의 수보다 많을 경우 늑대의 수를 0으로 만들어 리턴해 주었습니다. 단순한 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
#include <iostream>
#include <string>
#include <queue>
using namespace std;
 
int r, c;
string a[250];
bool isVisit[250][250];
int dx[] = { 00-11 };
int dy[] = { -1100 };
 
pair<intint> simulate(int i, int j) {
 
    int s = 0, w = 0;
    queue<pair<int,int>> q;
    if (a[i][j] == 'o') s++;
    if (a[i][j] == 'v') w++;
    isVisit[i][j] = true;
    q.emplace(i, j);
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            
            if (nx < 0 || nx >= r || ny < 0 || ny >= c || isVisit[nx][ny] == true|| a[nx][ny] == '#'continue;
 
            isVisit[nx][ny] = true;
 
            if (a[nx][ny] == 'o') s++;
            if (a[nx][ny] == 'v') w++;
 
            q.emplace(nx, ny);
        }
    }
 
    if (s > w) w = 0;
    else s = 0;
 
    return make_pair(s, w);
}
 
int main() {
 
    cin >> r >> c;
    memset(isVisit, falsesizeof(isVisit));
 
    for (int i = 0; i < r; i++) {
        cin >> a[i];
    }
    
    int sheep = 0, wolf = 0;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            
            if (isVisit[i][j] == truecontinue;
 
            if (a[i][j] == 'o' || a[i][j] == 'v') {
                auto n = simulate(i, j);
                sheep += n.first;
                wolf += n.second;
            }
        }
    }
    cout << sheep << ' ' << wolf << '\n';
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter
 

 

 
제출 결과
 

 

 

문제 출처

 

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

 

3184번: 양

문제 미키의 뒷마당에는 특정 수의 양이 있다. 그가 푹 잠든 사이에 배고픈 늑대는 마당에 들어와 양을 공격했다. 마당은 행과 열로 이루어진 직사각형 모양이다. 글자 '.' (점)은 빈 필드를 의미하며, 글자 '#'는 울타리를, 'o'는 양, 'v'는 늑대를 의미한다. 한 칸에서 수평, 수직만으로 이동하며 울타리를 지나지 않고 다른 칸으로 이동할 수 있다면, 두 칸은 같은 영역 안에 속해 있다고 한다. 마당에서 "탈출"할 수 있는 칸은 어떤 영역에도 속하지

www.acmicpc.net

 

문제 해설

 

가능한 부분 수열의 합을 모두 벡터에 넣어주고 벡터를 정렬한 후 unique함수를 활용하여 중복을 배열의 가장 뒤로 보내주었습니다. 이후 인덱스를 비교하여 가장 작은 자연수를 출력시켜 주었습니다.

 

 

코드

 

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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
 
    int n;
    int d[20];
    cin >> n;
    vector <int> v;
 
    for (int i = 0; i < n; i++) {
        cin >> d[i];
    }
 
    v.push_back(0);
    v.push_back(d[0]);
 
    for (int i = 1; i < n; i++) {
        int x = v.size();
        for (int j = 0; j < x; j++) {
            v.push_back(v[j] + d[i]);
        }
    }
 
    sort(v.begin(), v.end());
    unique(v.begin(), v.end());
 
 
    for(int i = 1; i <= v.size(); i++){
        if (i == v.size()) {
            cout << i << '\n';
        }
        else if(v[i] != i){
            cout << i << '\n';
            break;
        }
    }
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

14225번: 부분수열의 합

수열 S가 주어졌을 때, 수열 S의 부분 수열의 합으로 나올 수 없는 가장 작은 자연수를 구하는 프로그램을 작성하시오. 예를 들어, S = [5, 1, 2]인 경우에 1, 2, 3(=1+2), 5, 6(=1+5), 7(=2+5), 8(=1+2+5)을 만들 수 있다. 하지만, 4는 만들 수 없기 때문에 정답은 4이다.

www.acmicpc.net

 

+ Recent posts