swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5LtJYKDzsDFAXc&categoryId=AV5LtJYKDzsDFAXc&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 방 정보를 입력받는다.

2. 방을 최대로 이동할 수 있을 때의 방 숫자와, 그 때 이동한 방 개수를 출력한다.

 

<해법>

1. 이동한 방 개수를 구하는 방법

=> 이동한 방 개수를 구하는 방법은 굉장히 간단합니다. 각 좌표마다 방을 이동할 수 있을때까지 이동하고, 총 개수를 구합니다. 하지만 여기서 조금 더 생각하면 중복을 제거할 수 있는 원리가 보입니다.

위 그림과 같이 4번 방에서 이동할 수 있는 방의 개수는 (1+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
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
#include <iostream>
#include <string.h>
#include <algorithm>
 
using namespace std;
 
//구조체 : 좌표
struct pos {
    int x, y;
};
 
//4방향 : 북, 동, 남, 서
int di[] = { -1,0,1,0 };
int dj[] = { 0,1,0,-1 };
 
int map[1000][1000];
int cache[1000][1000]; //DP 저장 배열
int N;
int Answer_RoomNum;
int Answer_RoomCnt;
 
//현재 좌표가 범위 안에 있는지 판단
bool isInner(pos p) {
    if (p.x < 0 || p.y < 0 || p.x >= N || p.y >= N) {
        return false;
    }
    return true;
}
 
//현재 좌표에서 다음 좌표로 이동할 수 있는지 판단
bool canGo(pos cur, pos nxt) {
    if (map[cur.x][cur.y] + 1 == map[nxt.x][nxt.y]) {
        return true;
    }
    return false;
}
 
//DP 풀이
int move(pos cur) {
 
    int& ret = cache[cur.x][cur.y];
 
    if (ret != -1) {
        return ret;
    }
 
    ret = 1;
 
    for (int i = 0; i < 4; i++) {
        pos nxt = cur;
        nxt.x += di[i];
        nxt.y += dj[i];
 
        if (!isInner(nxt)) {
            continue;
        }
 
        if (canGo(cur, nxt)) {
 
            /*
            현재 좌표에서 이동할 수 있는 방의 수 = 1 + 다음 좌표에서 이동할 수 있는 방의 수
            */
            ret += move(nxt);
        }
    }
 
    return ret;
}
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        memset(map, 0sizeof(map));
        memset(cache, -1sizeof(cache));
        N = 0;
        Answer_RoomNum = 0, Answer_RoomCnt = 0;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cin >> map[i][j];
            }
        }
 
        //해법
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
 
                //{i, j}에서 이동할 수 있는 방의 개수 구하기
                int Tmp_RoomCnt = move({ i, j });
 
                //결과 갱신
                if (Tmp_RoomCnt > Answer_RoomCnt) {
                    Answer_RoomCnt = Tmp_RoomCnt;
                    Answer_RoomNum = map[i][j];
                }
                else if (Tmp_RoomCnt == Answer_RoomCnt) {
                    Answer_RoomNum = min(Answer_RoomNum, map[i][j]);
                }
            }
        }
 
        //결과 출력
        cout << "#" << test_case << " " << Answer_RoomNum << " " << Answer_RoomCnt << "\n";
    }
 
    //종료
    return 0;
}
 

 

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

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWNcJ2sapZMDFAV8&categoryId=AWNcJ2sapZMDFAV8&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 학생들의 현재 방과 돌아가야할 방 번호들을 입력받는다.

2. 학생들이 모두 이동하는데 걸리는 최소 시간을 출력한다.

 

<해법>

1. 최소 이동시간의 경우 이해하기

=> 가장먼저, 이동시간이 최소가 되는 경우가 언제인지 생각해 보아야합니다.

곰곰히 생각해보면, 한번에 학생들을 많이 움직여야 합니다. 그러기 위해서는 앞 번호 방부터 복도가 겹치지 않게해서 학생들을 많이 움직이게 해야합니다.

따라서, 저는 학생들의 방 정보를 현재 방 번호 크기 기준으로 정렬하였습니다.

 

2. 최소 이동시간 구하기

=> 정렬한 방 정보를 이용하여, 복도가 겹치지 않게 이동할 학생들을 정합니다. 이 때, 사용되는 복도를 유의해야합니다. 이 문제는 복도를 중앙에 두고 위, 아래로 방이 있습니다.

이 말은, 1 -> 3 방으로 가는 학생과 4 -> 6 방으로 가는 학생의 복도가 겹친다는 뜻 입니다.

따라서, 단순히 사용되는 복도를 설정할 때, 방의 숫자로만 하시면 안됩니다.

저는 위와 같은 경우를 해결하기 위해서, 1 -> 3 방으로 가는 학생을 1 -> 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
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
 
using namespace std;
 
//구조체 : 방 정보
struct room {
    //시작 방 번호, 도착 방 번호
    int start, finish;
};
 
int N;
vector<room> v;
bool visited[400];
int answer;
 
//정렬 기준(시작 방 번호에 따라 정렬)
bool compare(room r1, room r2) {
    if (r1.start == r2.start) {
        return r1.finish < r2.finish;
    }
    return r1.start < r2.start;
}
 
bool allStudentReturn() {
    for (int i = 0; i < N; i++) {
        if (!visited[i]) {
            return false;
        }
    }
    return true;
}
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0;
        v.clear();
        memset(visited, falsesizeof(visited));
        answer = 0;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
 
            int room1, room2;
            cin >> room1 >> room2;
 
            //작은 번호 방에서 큰 번호 방으로 출발하도록 설정
            if (room1 > room2) {
                v.push_back({ room2, room1 });
            }
            else {
                v.push_back({ room1, room2 });
            }
        }
 
        //정렬(시작 방 번호가 작은 순서대로)
        sort(v.begin(), v.end(), compare);
 
        //시간 계산
        while (true) {
 
            //모든 학생이 방으로 돌아간 경우 -> 종료
            if (allStudentReturn()) {
                break;
            }
 
            int finish = 0;
 
            //모든 학생 점검
            for (int i = 0; i < N; i++) {
 
                //아직 방을 이동하지 못하였고 && 복도가 겹치지 않을 경우 -> 동시에 움직일 수 있음
                if (!visited[i] && v[i].start > finish) {
 
                    //방문 처리
                    visited[i] = true;
 
                    //방이 홀수인 경우 -> 쓰는 복도는 결국 방 번호가 짝수인 경우와 같다
                    if (v[i].finish % 2 == 1) {
                        finish = v[i].finish + 1;
                    }
                    else {
                        finish = v[i].finish;
                    }
                }
            }
 
            //시간 + 1
            answer++;
        }
 
        //결과 출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}
 

 

그리디 알고리즘과 구현에 대해 알아볼 수 있는 문제였습니다.

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWHPkqBqAEsDFAUn&categoryId=AWHPkqBqAEsDFAUn&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 문제의 배점들을 입력받는다.

2. 배점들로 만들 수 있는 점수의 가짓수를 출력한다.

 

<해법>

1. 점수의 가짓수를 계산하는 방법

=> 예를 들어서 설명해보겠습니다. 만약, 주어진 배점들로 만들 수 있는 점수가 0, 3, 5, 8, 10이고, 새로운 문제의 배점은 5점이라고 가정하겠습니다. 이 때, 만들 수 있는 새로운 점수는 기존에 가지고 있던 점수에 새로운 문제 배점을 더한 값들일 것입니다. 0+5, 3+5, 5+5, 8+5, 10+5 -> 5, 8, 10, 13, 15 입니다. 여기서 5, 8, 10은 중복된 값이므로 제외하면, 만들 수 있는 점수들은 0, 3, 5, 8, 10, 13, 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
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
#include <iostream>
#include <string.h>
#include <vector>
 
using namespace std;
 
int N;
int score[100];
bool visited[10001];
vector<int> canScore;
int answer;
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0;
        memset(score, 0sizeof(score));
        memset(visited, false , sizeof(visited));
        canScore.clear();
        answer = 0;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            cin >> score[i];
        }
 
        //해법
        //0점부터 시작
        canScore.push_back(0);
        visited[0= true;
 
        for (int i = 0; i < N; i++) {
            
            //현재 만들 수 있는 점수의 개수(벡터 사이즈) 저장
            int v_size = canScore.size();
 
            for (int j = 0; j < v_size; j++) {
 
                //새로운 점수 = 현재 만들 수 있는 점수 + 새로운 배점
                int newScore = canScore[j] + score[i];
 
                //이전에 만들 수 있는 점수가 아닌 경우 -> 벡터에 저장
                if (!visited[newScore]) {
                    canScore.push_back(newScore);
                    visited[newScore] = true;
                }
            }
        }
 
        //결과 갱신
        answer = canScore.size();
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}
 

 

수학적인 사고에 대해 알아볼 수 있는 문제였습니다.


위 문제보다 조금 더 어렵지만, 같은 사고를 이용하여 푸는 문제입니다. 아래 문제도 풀어보시면 도움이 될 것 같습니다!

www.acmicpc.net/problem/2437

 

2437번: 저울

하나의 양팔 저울을 이용하여 물건의 무게를 측정하려고 한다. 이 저울의 양 팔의 끝에는 물건이나 추를 올려놓는 접시가 달려 있고, 양팔의 길이는 같다. 또한, 저울의 한쪽에는 저울추들만 놓

www.acmicpc.net

 

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV7GOPPaAeMDFAXB&categoryId=AV7GOPPaAeMDFAXB&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 정점 개수와 간선 정보를 입력받는다.

2. 한 정점에서 다른 정점으로 갈 수 있는 최장 경로를 계산하여 출력한다.

 

<해법>

1. 최장 경로를 계산하는 방법

=> 어떤 정점에서 출발해야하는지 모르기 때문에, 모든 정점에서 출발해보아야 합니다. 따라서, 모든 정점에서 출발하여 겹치지 않고 갈 수 있는 정점까지 가서 최장경로를 계산합니다.

 

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
#include <iostream>
#include <string.h>
 
using namespace std;
 
int N, M;
int edge[11][11];
bool visited[11];
int answer;
 
void findLongestPath(int index, int pathCount) {
 
    //결과 갱신
    if (pathCount > answer) {
        answer = pathCount;
    }
 
    //현재 정점에서 갈 수 있는 모든 정점 가보기
    for (int i = 1; i <= N; i++) {
 
        //간선이 있고, 이전에 방문한 적이 없는 경우 -> 방문
        if (edge[index][i] && !visited[i]) {
            visited[i] = true;
            findLongestPath(i, pathCount + 1);
            visited[i] = false;
        }
    }
}
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0, M = 0;
        memset(edge, 0sizeof(edge));
        memset(visited, falsesizeof(visited));
        answer = 0;
 
        //입력
        cin >> N >> M;
        for (int i = 0; i < M; i++) {
            int x, y;
            cin >> x >> y;
            
            //간선 정보 등록
            edge[x][y] = 1;
            edge[y][x] = 1;
        }
 
        //해법
        /*
        1번 정점부터 N번 정점까지 모두 최장경로 찾기
        */
        for (int i = 1; i <= N; i++) {
            visited[i] = true;
            findLongestPath(i, 1);
            visited[i] = false;
        }
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}
 

 

브루트포스에 대해 알아볼 수 있는 문제였습니다.

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV7GLXqKAWYDFAXB&categoryId=AV7GLXqKAWYDFAXB&categoryType=CODE

 

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
#include <iostream>
#include <stdio.h>
#include <string.h>
 
using namespace std;
 
int N;
int map[49][49];
int answer;
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0;
        memset(map, 0sizeof(map));
        answer = 0;
 
        //입력
        cin >> N;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                scanf_s("%1d"&map[i][j]);
            }
        }
 
        //해법
        /*
        위 삼각형, 아래 삼각형 나누어서 계산(마름모 별찍기 응용 문제)
        */
        for (int i = 0; i < N / 2; i++) {
            for (int j = N / 2 - i; j <= N / 2 + i; j++) {
                answer += map[i][j];
            }
        }
        for (int i = 0; i <= N / 2; i++) {
            for (int j = i; j < N - i; j++) {
                answer += map[i + N / 2][j];
            }
        }
 
        //결과 출력
        cout << "#" << test_case << " " << answer << "\n";
    }
    
    //종료
    return 0;
}
 

 

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

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

[C++] SWEA 3752 - 가능한 시험 점수  (0) 2021.01.13
[C++] SWEA 2814 - 최장 경로  (0) 2021.01.12
[C++] SWEA 2817 - 부분 수열의 합  (0) 2021.01.08
[C++] SWEA 1215 - 회문1  (0) 2021.01.05
[C++] SWEA 1208 - Flattern  (0) 2021.01.02

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV7IzvG6EksDFAXB&categoryId=AV7IzvG6EksDFAXB&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 주어진 수열의 각 원소를 모든 경우에 따라 더해본다.

2. 원소들의 합이 K인 경우의 수를 출력한다.

 

<해법>

가장 기본적인 브루트 포스 문제라고 생각합니다. 원소를 고를 때 중복을 제거하는 방식을 고려하여 구현하였습니다.

 

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>
 
using namespace std;
 
int N, K;
int arr[20];
int answer;
 
void makeSum(int idx, int sum) {
 
    //합이 K를 넘는 경우 -> 더 이상 더할 필요없으므로 종료
    if (sum > K) {
        return;
    }
 
    //합이 K인 경우 -> answer갱신 후 종료
    if (sum == K) {
        answer++;
        return;
    }
 
    //자신보다 뒤에 있는 원소 더해보기(중복 제거 위해)
    for (int i = idx; i < N; i++) {
        makeSum(i + 1, sum + arr[i]);
    }
}
 
int main() {
 
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0, K = 0;
        answer = 0;
 
        //입력
        cin >> N >> K;
        for (int i = 0; i < N; i++) {
            cin >> arr[i];
        }
 
        //해법
        /*
        모든 원소 다 더해보기
        */
        makeSum(00);
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}
 

 

브루트포스에 대해 알아볼 수 있는 문제였습니다.

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

[C++] SWEA 2814 - 최장 경로  (0) 2021.01.12
[C++] SWEA 2805 - 농작물 수확하기  (0) 2021.01.08
[C++] SWEA 1215 - 회문1  (0) 2021.01.05
[C++] SWEA 1208 - Flattern  (0) 2021.01.02
[C++] SWEA 1244 - 최대 상금  (0) 2020.12.31

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14QpAaAAwCFAYi&categoryId=AV14QpAaAAwCFAYi&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 8x8 글자판을 입력받는다.

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
#include <iostream>
#include <string>
#include <string.h>
 
using namespace std;
 
int palindrome_length;
char map[8][8];
int answer;
 
//해당 문자열이 회문인지 판단하는 함수
bool isPalindrome(string s) {
 
    for (int i = 0; i < s.length() / 2; i++) {
        if (s[i] != s[s.length() - 1 - i]) {
            return false;
        }
    }
 
    return true;
}
 
//해당 좌표에 회문이 몇 개인지 판단하는 함수
int countPalindrome(int x, int y) {
 
    int palindromeCnt = 0;
 
    //아래쪽에 회문이 있는지 확인
    if (x + palindrome_length <= 8) {
 
        //아래쪽 문자열을 모으고
        string str = "";
        for (int i = 0; i < palindrome_length; i++) {
            str += map[x + i][y];
        }
 
        //문자열이 회문인지 확인
        if (isPalindrome(str)) {
            palindromeCnt++;
        }
    }
 
    //오른쪽에 회문이 있는지 확인
    if (y + palindrome_length <= 8) {
 
        //오른쪽 문자열을 모으고
        string str = "";
        for (int i = 0; i < palindrome_length; i++) {
            str += map[x][y + i];
        }
 
        //문자열이 회문인지 확인
        if (isPalindrome(str)) {
            palindromeCnt++;
        }
    }
 
    return palindromeCnt;
}
 
int main() {
 
    int test_case;
    int T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        palindrome_length = 0;
        memset(map, '#'sizeof(map));
        answer = 0;
 
        //입력
        cin >> palindrome_length;
        for (int i = 0; i < 8; i++) {
            string tmp;
            cin >> tmp;
            for (int j = 0; j < 8; j++) {
                map[i][j] = tmp[j];
            }
        }
 
        //해법
        /*
        각 좌표마다 아래쪽 또는 오른쪽 방향에 회문이 있는지 확인
        */
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                answer += countPalindrome(i, j);
            }
        }
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}
 

 

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

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV139KOaABgCFAYh&categoryId=AV139KOaABgCFAYh&categoryType=CODE

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 평탄화 작업 횟수와 박스 개수를 입력받는다.

2. 평탄화 작업 수행 후, 최고점과 최저점의 차이를 출력한다.

 

<해법>

1. 평탄화 작업 수행 방법

=> 평탄화 작업에서 중요한 것은 최고점최저점 입니다. 평탄화 작업은 결국 최고점에서 최저점에게로 하나 주는 것이기 때문에 중간의 여러 값들은 중요하지 않습니다. 따라서, 정렬을 통해 최고점과 최저점을 구하고 평탄화 작업을 수행합니다.

 

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
#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int main() {
 
    int test_case;
    int T = 10;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        int dumpCnt;
        vector<int> box;
 
        //입력
        cin >> dumpCnt;
        for (int i = 0; i < 100; i++) {
            int boxCnt;
            cin >> boxCnt;
            box.push_back(boxCnt);
        }
 
        //박스 개수 순서로 정렬
        sort(box.begin(), box.end());
 
        //평탄화 작업 수행
        for (int i = 0; i < dumpCnt; i++) {
 
            //가장 많은 박스에서 가장 적은 박스로 하나 넘기기
            box.back()--;
            box.front()++;
 
            sort(box.begin(), box.end());
 
            //차이가 1이하인 경우 -> 평탄화 종료
            if (box.back() - box.front() <= 1) {
                break;
            }
        }
 
        //출력
        cout << "#" << test_case << " " << box.back() - box.front() << "\n";
    }
 
    //종료
    return 0;
}
 

 

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

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

[C++] SWEA 2817 - 부분 수열의 합  (0) 2021.01.08
[C++] SWEA 1215 - 회문1  (0) 2021.01.05
[C++] SWEA 1244 - 최대 상금  (0) 2020.12.31
[C++] SWEA 2112 - 보호 필름  (0) 2020.05.19
[C++] SWEA 2117 - 홈 방범 서비스  (0) 2020.05.19

+ Recent posts