개발지식 먹는 하마 님의 블로그

프로그래머스 lv2 - 시소 짝꿍 본문

coding

프로그래머스 lv2 - 시소 짝꿍

devhippo 2025. 3. 5. 18:16

✏️ 문제 풀이

< 초기 접근 > 

- 최대공약수로 비율을 구하기

  • 두 Weight의 최대공약수를 구한다.
  • 최대공약수가 없는 경우 넘어간다.
  • 최대공약수가 있는 경우 기존 무게에 각각의 비율을 적용해 일치하는 경우의 수를 찾아 카운트한다.
이 경우 모든 비교에 대해 반복을 돌면서 최대공약수를 구해야 하기 때문에 비효율적으로 느껴졌다.
(프로그래머스의 C++은 최대공약수를 구하는 함수 GCD)

 

< 최종 접근 >

굳이 최대공약수를 구할 필요없이 두 무게가 제시된 비율에 해당하는지 확인만 하면 된다.
따라서 더 간단한 방법을 사용하고자 했다.

X : Y = 2 : 3
3X = 2Y
3X/2 = Y

 

비교 대상 중 하나인  Weight에 비율을 곱하고 나누어 시소의 균형을 이룰 수 있는 Y를 구하는 것이다.

이분탐색 Binary Search 사용하기

이분 탐색에는 lower_bound라는 기능이 있다.
정렬된 배열에 대해서 특정 값 X가 처음 존재하는 위치를 반환한다.
주어진 비율을 충족하는 두 무게를 알고 있기 때문에 lower_bound를 통해서
이와 일치하는 원소의 개수를 카운트하면 되는 것이다.

1) 데이터 정렬하기

이분 탐색은 정렬된 데이터를 기반으로 하기 때문에 weights를 정렬한다.

    sort(weights.begin(), weights.end());

 

2) 비율을 만족하는 무게를 구한다.

int w2 = (weights[i] * b) / a;

 

3) 계산된 무게와 동일한 데이터의 개수를 센다.

//계산된 무게 w2와 일치하는 값이 처음있는 위치를 찾기
auto it = lower_bound(weights.begin() + i + 1, weights.end(), w2);
//데이터의 끝이 아니고, 계산된 무게와 동일할 때까지
while (it != weights.end() && *it == w2) {
    answer++; //개수 카운트
    it++;     //다음 위치로 이동
}

upper_bound를 사용해서 계산된 무게와 일치하는 값이 가장 마지막에 있는 위치를 가져와 while문을 돌 수도 있다.

 

🖥️ 전체 코드

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

using namespace std;

long long solution(vector<int> weights) {
    long long answer = 0;
    
    sort(weights.begin(), weights.end());
    
    vector<pair<int, int>> ratios = {{1, 1}, {2, 3}, {2, 4}, {3, 4}};
    
     for (int i = 0; i < weights.size(); i++) {
        for (auto &[a, b] : ratios) {
            int w2 = (weights[i] * b) / a;
            if ((weights[i] * b) % a == 0) { //딱 나눠 떨어지면
                auto it = lower_bound(weights.begin() + i + 1, weights.end(), w2);
                while (it != weights.end() && *it == w2) {
                    answer++;
                    it++;
                }
            }
        }
    }
    
    return answer;
}

 

'coding' 카테고리의 다른 글

프로그래머스 lv2 - 거리두기 확인하기  (0) 2025.03.12
프로그래머스 lv2 - 멀쩡한 사각형  (0) 2025.03.07
1316번 - 그룹 단어 체커  (0) 2025.02.28
1541번 - 잃어버린 괄호  (0) 2025.02.27
13305번 - 주유소  (0) 2025.02.26