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

 

SW Expert Academy

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

swexpertacademy.com

<풀이>

1. 한 지점에서 가로로 M만큼 꿀을 채취했을 때, 합은 C이하이면서 제곱의 합은 가장 큰 경우를 찾고, 그 때 제곱의 합을 다른 배열에 저장한다.(모든 지점에서 이 행위를 반복한다.)

2. (A양봉업자 최대이윤 + B양봉업자 최대이윤)의 최댓값을 구해서 출력한다.

 

<해법>

1. 한 지점에서 가로로 M만큼 꿀을 채취했을 때, 최대이윤을 구하는 방법

=> 문제를 간단하게 생각(합은 C이하, 제곱의 합이 가장 큰 경우 생각X)하면, 숫자들의 '조합'을 구하는 문제와 같습니다. 저는 재귀함수를 이용해서 먼저 조합을 구현하였고, 그 이후에 조건들을 덧붙여가며 문제를 해결했습니다.

 

(전체적인 문제를 해결한 흐름입니다.)

 

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
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int N, M, C;
int honeyMap[10][10];       //주어진 입력 맵
int maxProfitMap[10][10];   //최대 이윤 맵
 
//벡터 v의 원소들로 조합하여, 합은 C보다 작으면서 가장 큰 이윤을 찾는 함수
int findMaxProfit(vector<int> v, int idx, int sum, int profit) {
 
    if (sum > C) {
        return 0;
    }
 
    int maxProfit = 0;
    maxProfit = max(maxProfit, profit);
 
    if (idx >= M) {
        return maxProfit;
    }
 
    for (int i = idx; i < M; i++) {
        maxProfit = max(maxProfit, findMaxProfit(v, i + 1, sum + v[i], profit + (v[i] * v[i])));
    }
    
    return maxProfit;
}
 
int main() {
    int test_case;
    int T;
 
    cin >> T;
 
    for (test_case = 1; test_case <= T; test_case++) {
 
        //초기화
        N = 0, M = 0, C = 0;
        memset(honeyMap, 0sizeof(honeyMap));
        memset(maxProfitMap, 0sizeof(maxProfitMap));
        int answer = 0;
 
        //입력
        cin >> N >> M >> C;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cin >> honeyMap[i][j];
            }
        }
 
        /* 해법 */
        //1. 각 지점에서 가로로 M만큼 꿀을 채취했을 때, 가장 많은 이윤을 찾아 저장
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= N - M; j++) {
                vector<int> v;
                for (int k = 0; k < M; k++) {
                    v.push_back(honeyMap[i][j + k]);
                }
                maxProfitMap[i][j] = findMaxProfit(v, 000);
            }
        }
 
        //2. (A양봉업자 최대이윤 + B양봉업자 최대이윤) 최댓값 구하기
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= N - M; j++) {
                int maxProfitSum = maxProfitMap[i][j];
 
                int maxProfit = 0;
                for (int k = i; k < N; k++) {
                    int startL = 0;
                    if (k == i) {
                        startL = j + M;
                    }
                    for (int l = startL; l <= N - M; l++) {
                        maxProfit = max(maxProfit, maxProfitMap[k][l]);
                    }
                }
 
                maxProfitSum += maxProfit;
                answer = max(answer, maxProfitSum);
            }
        }
 
        //출력
        cout << "#" << test_case << " " << answer << "\n";
    }
 
    //종료
    return 0;
}

 

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

https://school.programmers.co.kr/learn/courses/30/lessons/118668

 

프로그래머스

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

programmers.co.kr

<풀이>

1. 알고력, 코딩력, 문제들을 입력받는다.

2. 문제들을 풀며 알고력, 코딩력을 향상시킨다.

3. 모든 문제들을 풀 수 있는 알고력과 코딩력을 얻는 최단시간을 반환한다.

 

<해법>

1. 문제를 접근해 나가는 방법(저가 문제를 풀었던, 지극히 개인적인 방법입니다.)

=>

(1) '코딩문제를 어떤 순서로 풀어야할까?'를 먼저 고민해야합니다. 내 알고력과 코딩력에 가장 근접한 문제? 아닙니다. 알고력과 코딩력을 1시간 당으로 계산해서 가장 많이 올려줄 수 있는 문제? 아닙니다. 여러 방법을 생각해보면 모두 아니라는 것을 알 수 있습니다. 그렇다면, 남은 것은 모든 경우를 해보는 방법(브루트포스) 밖에 없습니다.

 

(2) 효율성은 일단 생각하지 않고, 정확성에만 초점을 둔 채 재귀를 이용해 구현합니다.

 

(3) 정확성 부분을 모두 통과가 되었다면, 어떻게 효율성을 높일지 생각해야합니다. 재귀를 이용한 브루트포스이므로 가장 먼저 메모이제이션을 떠올릴 수 있습니다. 따라서, 해당 코드에 메모이제이션을 추가하여 완성합니다.


사실... 저는 정확성 테스트 케이스 제한사항에 있는 '1 <= problems의 길이 <= 6'을 보고 재귀를 이용한 브루트포스를 떠올렸습니다. 그리고, 바로 효율성은 메모이제이션을 떠올릴 수 있었습니다. 위에 해법을 거창하게 써놨지만, 결국 저는 꼼수로 풀었습니다ㅜㅜ.

 

정확성 코드와 효율성 코드를 모두 올리겠습니다. 두 개의 차이점을 보시면서, 메모이제이션을 느끼셨으면 좋겠습니다.

 

- 정확성 코드

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 <string>
#include <vector>
#include <algorithm>
#include <iostream>
#define INF 987654321
 
using namespace std;
 
vector<vector<int>> problems;
int maxAlp, maxCop;
int answer;
 
int solveProblems(int alp, int cop) {
 
    //종료조건
    if (alp >= maxAlp && cop >= maxCop) {
        return 0;
    }
 
    int ret = INF;
 
    for (int i = 0; i < problems.size(); i++) {
        //문제를 풀 수 있는 경우
        if (alp >= problems[i][0&& cop >= problems[i][1]) {
 
            //문제를 풀 필요가 없는 경우
            //(1) alp가 maxAlp를 넘었는데, 문제가 cop를 올려주지 못할 경우
            if (alp >= maxAlp && problems[i][3== 0) {
                continue;
            }
 
            //(2) cop가 maxCop를 넘었는데, 문제가 alp를 올려주지 못할 경우
            if (cop >= maxCop && problems[i][2== 0) {
                continue;
            }
            
            //재귀
            ret = min(ret, 
                      solveProblems(alp + problems[i][2], cop + problems[i][3]) + problems[i][4]);
        }
    }
 
    return ret;
}
 
int solution(int alp, int cop, vector<vector<int>> problems_given) {
 
    //초기화
    problems = problems_given;
    problems.push_back({ 0,0,1,0,1 });
    problems.push_back({ 0,0,0,1,1 });
    maxAlp = 0;
    maxCop = 0;
    answer = -1;
 
    /* 해법 */
    //1. problems의 alp, cop 최댓값 구하기
    for (int i = 0; i < problems_given.size(); i++) {
        if (problems_given[i][0> maxAlp) {
            maxAlp = problems_given[i][0];
        }
        if (problems_given[i][1> maxCop) {
            maxCop = problems_given[i][1];
        }
    }
 
    //2. 브루트포스(재귀)
    answer = solveProblems(alp, cop);
 
    //반환
    return answer;
}

 

- 효율성 코드

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
#include <string>
#include <vector>
#include <algorithm>
#include <string.h>
#include <iostream>
#define INF 987654321
 
using namespace std;
 
vector<vector<int>> problems;
int maxAlp, maxCop;
int cache[151][151];
int answer;
 
int solveProblems(int alp, int cop) {
 
    //캐시 크기 벗어남 방지
    if (alp > maxAlp) {
        alp = maxAlp;
    }
    if (cop > maxCop) {
        cop = maxCop;
    }
 
    //alp, cop가 최대치 달성됐을 경우
    if (alp == maxAlp && cop == maxCop) {
        return 0;
    }
 
    int& ret = cache[alp][cop];
 
    //메모이제이션
    if (cache[alp][cop] != -1) {
        return ret;
    }
 
    ret = INF;
 
    for (int i = 0; i < problems.size(); i++) {
 
        //문제를 풀 수 있는 경우
        if (alp >= problems[i][0&& cop >= problems[i][1]) {
 
            //문제를 풀 필요가 없는 경우
            //(1) alp가 maxAlp가 되었는데, 문제가 cop를 올려주지 못할 경우
            if (alp == maxAlp && problems[i][3== 0) {
                continue;
            }
 
            //(2) cop가 maxCop가 되었는데, 문제가 alp를 올려주지 못할 경우
            if (cop == maxCop && problems[i][2== 0) {
                continue;
            }
 
            //재귀
            ret = min(ret, 
                      solveProblems(alp + problems[i][2], cop + problems[i][3]) + problems[i][4]);
        }
    }
 
    return ret;
}
 
int solution(int alp, int cop, vector<vector<int>> problems_given) {
 
    //초기화
    problems = problems_given;
    problems.push_back({ 0,0,1,0,1 });
    problems.push_back({ 0,0,0,1,1 });
    maxAlp = 0;
    maxCop = 0;
    memset(cache, -1sizeof(cache));
    answer = -1;
 
    /* 해법 */
    //1. problems의 alp, cop 최댓값 구하기
    for (int i = 0; i < problems_given.size(); i++) {
        if (problems_given[i][0> maxAlp) {
            maxAlp = problems_given[i][0];
        }
        if (problems_given[i][1> maxCop) {
            maxCop = problems_given[i][1];
        }
    }
 
    //2. 메모이제이션
    answer = solveProblems(alp, cop);
 
    //반환
    return answer;
}

 

메모이제이션에 대해 알아볼 수 있는 문제였습니다.

https://school.programmers.co.kr/learn/courses/30/lessons/118667

 

프로그래머스

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

programmers.co.kr

<풀이>

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
#include <string>
#include <vector>
#include <iostream>
 
using namespace std;
 
int solution(vector<int> queue1, vector<int> queue2) {
 
    //선언
    int answer;                         //-> 정답
    vector<int>::iterator ptr1, ptr2;   //-> 큐 포인터
    long long sum_all, sum1, sum2;      //-> 큐1+큐2합, 큐1합, 큐2합
 
    //초기화
    answer = 0;
    ptr1 = queue1.begin(), ptr2 = queue2.begin();
    sum_all = 0, sum1 = 0, sum2 = 0;
 
    /* 해법 */
    //1. 큐1, 큐2, 큐1+큐2 원소 합 구하기
    for (int i = 0; i < queue1.size(); i++) {
        sum1 += queue1[i];
        sum2 += queue2[i];
    }
    sum_all = sum1 + sum2;
 
    //2. 큐1+큐2 원소 합이 홀수일 경우 -> 불가능
    if (sum_all % 2 != 0) {
        answer = -1;
    }
    else {
        //3. 큐1, 큐2에 있는 두 개의 포인터를 조종하며 원소 합 구하기
        while (true) {
 
            //종료조건1 -> 두 큐의 합이 같을 경우
            if (sum1 == sum2) {
                break;
            }
 
            //종료조건2 -> 포인터1이 큐2 끝까지 갔을 경우 or 포인터2가 큐1 끝까지 갔을 경우(탐색완료)
            if (ptr1 == queue2.end() || ptr1 == queue1.end()) {
                answer = -1;
                break;
            }
 
            //큐의 포인터 옮기기
            if (sum1 > sum2) {
                sum1 -= *ptr1;
                sum2 += *ptr1;
                
                ptr1++;
                if (ptr1 == queue1.end()) {
                    ptr1 = queue2.begin();
                }
            }
            else {
                sum2 -= *ptr2;
                sum1 += *ptr2;
                
                ptr2++;
                if (ptr2 == queue2.end()) {
                    ptr2 = queue1.begin();
                }
            }
 
            answer++;
        }
    }
 
    //반환
    return answer;
}

 

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

https://school.programmers.co.kr/learn/courses/30/lessons/118666

 

프로그래머스

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

programmers.co.kr

<풀이>

1. 질문지와 선택지를 입력받는다.

2. 질문지와 선택지에 따라서 성격유형 점수를 계산한다.

3. 계산된 점수에 따라서 성격유형을 반환한다.

 

<해법>

1. '성격 유형 점수판' 만들기

=> 이 문제는 결국 '성격 유형 점수판'을 구현하는 것이 관건입니다. 저는 map 자료구조를 사용해서 구현하였습니다.

 

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
#include <string>
#include <vector>
#include <map>
#include <iostream>
 
using namespace std;
 
string solution(vector<string> survey, vector<int> choices) {
 
    //선언
    string answer;      //--> 출력 정답
    char c[4][2= {    //--> 성격유형 지표
        {'R''T'},
        {'C''F'},
        {'J''M'},
        {'A''N'},
    };      
    map<charint> m;   //--> 성격유형 점수판
    
    //초기화
    answer = "";
 
    /* 해법 */
    for (int i = 0; i < survey.size(); i++) {
 
        //1. 점수 계산
        //해당 성격유형 점수 더해주기
        if (choices[i] < 4) {
            m[survey[i][0]] += (4 - choices[i]);
        }
        else {
            m[survey[i][1]] += (choices[i] - 4);
        }
    }
 
    //2. 성격유형 모음
    for (int i = 0; i < 4; i++) {
        if (m[c[i][0]] >= m[c[i][1]]) {
            answer += c[i][0];
        }
        else {
            answer += c[i][1];
        }
    }
 
    //반환
    return answer;
}

 

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

programmers.co.kr/learn/courses/30/lessons/64063

 

코딩테스트 연습 - 호텔 방 배정

 

programmers.co.kr

<풀이>

1. 고객이 원하는 방 정보를 입력받는다.

2. 규칙에 따라 방을 배정하고, 배정된 방을 반환한다.

 

<해법>

1. "효율성 테스트"가 있는 문제의 마음가짐

=> 단순히 구현을 요구하는 문제가 아님을 깨달아야 합니다. 문제를 읽으면서, 어떤 알고리즘 또는 자료구조를 사용할지 생각해야합니다. 저는 어떤 방에 대한 다음 방의 정보를 저장하는 방법을 생각했고, 이 때 map자료구조를 사용하였습니다.

 

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 <string>
#include <vector>
#include <map>
 
using namespace std;
 
//Key: 방 번호, Value: 다음방 번호
map<long longlong long> m;
 
//어떤 방의 다음 방을 갱신하는 함수
long long findNextRoom(long long roomNum) {
    if (m[roomNum] == 0) {
        return roomNum;
    }
 
    return m[roomNum] = findNextRoom(m[roomNum]);
}
 
vector<long long> solution(long long k, vector<long long> room_number) {
    vector<long long> answer;
 
    /* 해법 */
    //어떤 방의 다음 방을 계속해서 갱신
    for (int i = 0; i < room_number.size(); i++) {
 
        if (m[room_number[i]] == 0) {
            answer.push_back(room_number[i]);
            m[room_number[i]] = findNextRoom(room_number[i] + 1);
        }
        else {
            long long foundRoom = findNextRoom(room_number[i]);
            answer.push_back(foundRoom);
            m[foundRoom] = findNextRoom(foundRoom + 1);
        }
    }
 
    //결과 반환
    return answer;
}
 

 

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

programmers.co.kr/learn/courses/30/lessons/64062

 

코딩테스트 연습 - 징검다리 건너기

[2, 4, 5, 3, 2, 1, 4, 2, 5, 1] 3 3

programmers.co.kr

<풀이>

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
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
 
using namespace std;
 
//해당 사람의 수가 징검다리를 건널 수 있는지 확인하는 함수
bool canCross(vector<int> stones, int peopleCnt, int k) {
 
    int stoneCnt = 0;
    for (int i = 0; i < stones.size(); i++) {
        if (stones[i] - peopleCnt < 0) {
            stoneCnt++;
            if (stoneCnt >= k) {
                return false;
            }
        }
        else {
            stoneCnt = 0;
        }
    }
    return true;
}
 
int solution(vector<int> stones, int k) {
    int answer = 0;
 
    /* 해법 */
    //건널 수 있는 사람의 수를 이분탐색
    int start = 0;
    int end = *max_element(stones.begin(), stones.end());
 
    while (start <= end) {
        int mid = (start + end/ 2;
 
        //mid수의 사람이 건널 수 있는지 확인
        if (canCross(stones, mid, k)) {
            answer = mid;
            start = mid + 1;
        }
        else {
            end = mid - 1;
        }
    }
 
    //결과 반환
    return answer;
}
 

 

이분탐색에 대해 알아볼 수 있는 문제였습니다.

programmers.co.kr/learn/courses/30/lessons/77486

 

코딩테스트 연습 - 다단계 칫솔 판매

민호는 다단계 조직을 이용하여 칫솔을 판매하고 있습니다. 판매원이 칫솔을 판매하면 그 이익이 피라미드 조직을 타고 조금씩 분배되는 형태의 판매망입니다. 어느정도 판매가 이루어진 후,

programmers.co.kr

<풀이>

1. 다단계 조직도와 판매 정보를 입력받는다.

2. 판매 이익을 자신의 추천인과 재분배하고, 각 사람들의 이익을 반환한다.

 

<해법>

1. 다단계 조직도를 정리하는 방법

=> 사람마다 자신의 추천인을 저장해놓습니다. map자료구조를 사용하여 key, value를 각각 이름으로 해놓을 수도 있습니다. 저는 실행시간 단축을 위해, 각 사람마다 인덱스(번호)를 부여하였고, 추천인 배열을 만들어서 사람의 인덱스에 추천인의 인덱스를 저장해놓는 방식으로 구현하였습니다.

 

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
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <string.h>
 
using namespace std;
 
map<stringint> m;
int parent[10000];
int profits[10000];
 
//이익 분배 함수
void divideProfit(int index, int profit) {
 
    //종료조건 : 민호까지 왔을 경우
    if (index == -1) {
        return;
    }
 
    //이익 분배
    int stolen = profit / 10;
    int myProfit = profit - stolen;
    profits[index] += myProfit;
 
    //종료조건 : 더 이상 나눌 이익이 없을 경우
    if (stolen == 0) {
        return;
    }
 
    //재귀
    divideProfit(parent[index], stolen);
}
 
vector<int> solution(vector<string> enroll, vector<string> referral, vector<string> seller, vector<int> amount) {
    vector<int> answer;
 
    //초기화
    memset(parent, 0sizeof(parent));
    memset(profits, 0sizeof(profits));
 
 
    /* 해법 */
    //1. 맵 자료구조에 {'이름' : 'index'} 저장
    for (int i = 0; i < enroll.size(); i++) {
        m[enroll[i]] = i;
    }
 
    //2. 각 index마다 추천인 index 저장
    for (int i = 0; i < referral.size(); i++) {
        if (referral[i] == "-") {
            parent[i] = -1;
        }
        else {
            parent[i] = m[referral[i]];
        }
    }
 
    //3. 이익분배
    for (int i = 0; i < seller.size(); i++) {
        divideProfit(m[seller[i]], amount[i] * 100);
    }
 
    //결과 저장
    for (int i = 0; i < enroll.size(); i++) {
        answer.push_back(profits[i]);
    }
 
    //결과 반환
    return answer;
}
 

 

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

programmers.co.kr/learn/courses/30/lessons/77485

 

코딩테스트 연습 - 행렬 테두리 회전하기

6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]

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
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <string>
#include <vector>
#include <string.h>
#include <algorithm>
 
using namespace std;
 
int map[101][101];
int minChanged;
 
//회전 함수
void rotate(int x1, int y1, int x2, int y2) {
 
    int start = map[x1][y1];
 
    for (int i = x1; i < x2; i++) {
        map[i][y1] = map[i + 1][y1];
        minChanged = min(minChanged, map[i][y1]);
    }
 
    for (int i = y1; i < y2; i++) {
        map[x2][i] = map[x2][i + 1];
        minChanged = min(minChanged, map[x2][i]);
    }
 
    for (int i = x2; i > x1; i--) {
        map[i][y2] = map[i - 1][y2];
        minChanged = min(minChanged, map[i][y2]);
    }
 
    for (int i = y2; i > y1 + 1; i--) {
        map[x1][i] = map[x1][i - 1];
        minChanged = min(minChanged, map[x1][i]);
    }
 
    map[x1][y1 + 1= start;
    minChanged = min(minChanged, map[x1][y1 + 1]);
}
 
vector<int> solution(int rows, int columns, vector<vector<int>> queries) {
    vector<int> answer;
 
    //초기화
    memset(map, 0sizeof(map));
 
    /* 해법 */
    //1. 맵 그리기
    for (int i = 1; i <= rows; i++) {
        for (int j = 1; j <= columns; j++) {
            map[i][j] = (i - 1* columns + j;
        }
    }
 
    //2. 쿼리에 따라 맵 회전하기
    for (int i = 0; i < queries.size(); i++) {
 
        minChanged = 10001;
 
        int x1, y1, x2, y2;
        x1 = queries[i][0];
        y1 = queries[i][1];
        x2 = queries[i][2];
        y2 = queries[i][3];
 
        //회전
        rotate(x1,y1,x2,y2);
 
        //결과 저장
        answer.push_back(minChanged);
    }
 
    //결과 반환
    return answer;
}
 

 

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

+ Recent posts