알고리즘/프로그래머스 2단계

프로그래머스 - 시소 짝꿍 - C++

게임만드는학생 2024. 9. 19. 15:39

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

 

프로그래머스

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

programmers.co.kr

 

#include <string>
#include <vector>
#include <unordered_map>
using namespace std;

long long solution(vector<int> weights) {
    long long answer = 0;

    unordered_map<int, int>um;
    for (int i = 0; i < weights.size(); i++)
        um[weights[i]]++;

    for (pair<int, int> item : um)
    {
        int key = item.first;
        if (um[key] >= 2)
            answer+=((long long)item.second*(item.second-1)/2);
        
        if(key*2%1==0&&um.find(key*2) != um.end())
            answer+=(long long)um[key]*um[key*2];
        if(key*3%2==0&&um.find(key*3/2)!=um.end())
            answer+=(long long)um[key]*um[key*3/2];
        if(key*4%3==0&&um.find(key*4/3)!=um.end())
            answer+=(long long)um[key]*um[key*4/3];
    }
    return answer;
}

 

이 문제는 시소 짝꿍이 되는 경우의 수를 구하는 문제이다. 

시소 짝꿍은 어느자리에 앉든 평형을 이룰수 있다면 짝꿍이다. 

각 자리는 2,3,4미터 중심에서 떨어져 있다. 즉 몸무게의 비율은 1:1, 1:2, 2:3, 3:4 의 경우의 수가 있다.

 

이를 unordered_map을 통해서 구현하였다. 

key를 통해 값을 찾기 때문에 탐색에 대한 시간이 O(1)이며 키에 대해서 수를 카운트도 할 수 있기 때문이다. 

 

 int key = item.first;
        if (um[key] >= 2)
            answer+=((long long)item.second*(item.second-1)/2);

먼저 for문을 돌며 1:1의 경우를 체크하는 코드이다. 

같은 몸무게가 두 명 이상일 경우 nC2 만큼 센다. 왜냐하면 weights의 각 몸무게는 각 사람을 나타내기 때문이다. 

같은 몸무게의 여러사람 중 두 명을 고르는 경우의 수를 계산한 것이다. 

 

if(key*2%1==0&&um.find(key*2) != um.end())
            answer+=(long long)um[key]*um[key*2];
        if(key*3%2==0&&um.find(key*3/2)!=um.end())
            answer+=(long long)um[key]*um[key*3/2];
        if(key*4%3==0&&um.find(key*4/3)!=um.end())
            answer+=(long long)um[key]*um[key*4/3];

그리고 각각 1:2, 2:3, 3:4 의 비율을 체크하는 경우이다. 

먼저 비율에 대한 계산을 하여 얻는 키가 유효한지 체크한다. 키는 정수형이기 때문에 key가 5가 된다면 5*3/2는 7.5라 유효하지 않게 되기 때문이다. 

그 후, 맵에서 찾아 있다면 key C 1 * (비율계산한 키값) C 1 만큼 센다. 

마찬가지로 여러 사람 중 한명을 선택하는 경우의 수이기 때문이다. 

 

answer에 더할 때 곱연산에서 반드시 long long으로 형변환을 해야한다. 최대 십만의 길이를 가지는 weights 에서 카운트가 4만이 넘어가는 두 수가 곱해지면 int형의 범위를 넘기기 때문이다. 

 

이렇게 for문을 돌고 리턴하면 된다.