알고리즘

[programmers] 숫자 카드 나누기

졔졔311 2023. 5. 15. 17:34
728x90
반응형

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

 

프로그래머스

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

programmers.co.kr

---------------------------------------------------핵심 알고리즘--------------------------------------------

 

공통 인수 찾기

 

---------------------------------------------------풀이----------------------------------------------------

 

맨 처음 arrayA와 arrayB를 오름차순이 되도록 sorting한다.

(이 방식을 거치지 않아도 통과는 되지만, 시간 차이가 매우 많이 나니까 하는 것이 좋을 것 같다.)

 

우선, get_common_factor() 함수를 이용해 arrayA의 공통인수를 찾는다.

이 함수에서는 arrayA를 모두 나눌 수 있는 수를 찾는 것이므로, arrayA[0](arrayA의 가장 작은 값)부터 2(나눌 수 있는 최소)까지를 비교한다.

각 값이 arrayA의 원소를 모두 나눌 수 있는지 all_divided()함수를 이용해 비교해 true이면 vector에 저장한다.

이렇게 하면 큰 값부터 내림차순으로 공통인수가 저장될 것이다.

all_divided()함수에서는 arrayA의 맨 뒤 가장 큰 값부터 factor로 나누어지는지를 비교해 true/false를 리턴한다.

 

이렇게 찾은 공통 인수들이 내림차순으로 저장된 common_factor 벡터를 얻었다.

여기에 공통 인수가 존재한다면, 큰 공통 인수부터 사용해 arrayB의 하나라도 나눌 수 있는지 체크한다.

is_factor_of()함수를 사용해 arrayB의 큰 값부터 나누어지는지 체크하고, true/false를 리턴한다.

모두 나눌 수 없다면 이 수가 정답이고, 더 작은 공통 인수에 대해서는 비교할 필요가 없으므로 종료한다.

 

같은 작업을 arrayB에 대해서도 수행한다.

 

모두 수행 후, 더 큰 값을 answer에 저장해 리턴한다.

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

bool all_divided(vector<int> &arr, int factor){
    for(int i = 0; i < arr.size(); i++){
        if(arr[arr.size()-1-i] % factor != 0){
            return false;
        }
    }
    return true;
}

// arr의 모든 공통 인수를 리턴.
vector<int> get_common_factor(vector<int> &arr){
    vector<int> com_fac;
    
    for(int i = arr[0]; i > 1; i--){
        if(all_divided(arr, i)){
            com_fac.push_back(i);
        }
    }
    
    return com_fac;
}

// factor가 arr의 원소들 중 인수가 되는지 리턴.
bool is_factor_of(int factor, vector<int> &arr){
    // 큰 수부터 계산
    for(int i = 0; i < arr.size(); i++){
        if(arr[arr.size()-1-i] % factor == 0){
            return true;
        }
    }
    return false;
}

// arrayA(B)의 인수이면서 arrayB(A)의 인수가 아닌 가장 큰 양의 정수=?
// 없다면 0 리턴.
int solution(vector<int> arrayA, vector<int> arrayB) {
    int answer = 0;
    sort(arrayA.begin(), arrayA.end());
    sort(arrayB.begin(), arrayB.end());
    // arrayA의 공통인수가 존재한다면,
    vector<int> common_factor = get_common_factor(arrayA);
    if(!common_factor.empty()){
        // 큰 수부터 비교
        for(int i = 0; i < common_factor.size(); i++){
            // arrayB의 인수가 아니라면 answer.
            if(!is_factor_of(common_factor[i], arrayB)){
                answer = common_factor[i];
                break;
            }
        }
    }
    // arrayB의 공통 인수가 존재한다면,
    common_factor.clear();
    common_factor = get_common_factor(arrayB);
    if(!common_factor.empty()){
        // 큰 수부터 비교
        for(int i = 0; i < common_factor.size(); i++){
            // arrayA의 인수가 아니라면 answer.
            if(!is_factor_of(common_factor[i], arrayA)){
                if(answer < common_factor[i]){
                    answer = common_factor[i];
                }
                break;
            }
        }
    }
    
    return answer;
}

 

---------------------------------------------------후기----------------------------------------------------

맨 처음 생각한건 수학 이론으로 공통 인수를 찾는 방식이었는데, 그 방법을 쓰지 않고 단순 비교로도 통과는 된다.

최대공약수를 찾는게 '유클리드 호제법'이던데 이 방식을 알아는 두자.

다만, 정렬을 잘 이용해서 최소의 비교만 한다면, 문제가 요구하는 바는 맞출 수 있다는거!

(솔직히 통과되는 것에 놀랐다)

728x90
반응형

'알고리즘' 카테고리의 다른 글

[programmers] 부대복귀  (0) 2023.05.16
[programmers] 등대  (1) 2023.05.16
[programmers] 숫자 타자 대회  (0) 2023.05.15
[programmers] 억억단을 외우자  (2) 2023.05.12
[programmers] 귤 고르기  (1) 2023.05.12