백준 & 프로그래머스

프로그래머스[2024 KAKAO WINTER INTERNSHIP]가장 많이 받은 선물.Java and Python

concho 2024. 1. 10. 17:55

# 다음달의 선물 여부 결정 알고리즘
#1. 두 사람이 선물을 주고받은 기록이 있고 같지 않은 경우:
#   1-1 이번달 까지 두 사람 사이에 더 많은 선물을 준 사람 선택 -> 뽑힌 사람은 선물하나 받음
#2. 두 사람이 선물을 주고받은 기록이 없거나 같은 경우:
#   2-1 선물 지수가 더 큰 사람 선택 -> 뽑힌 사람은 선물하나 받음
#   2-2 선물 지수마저 같다면 다음달엔 선물 X

 

나중엔 먼저 초기화를 진행하고 get메서드만 사용하면 될듯 함

import java.util.*;
class Solution {
    public int solution(String[] friends, String[] gifts) {
        int answer = 0;

        Map<String, HashMap<String, Integer>> myGivenGift = new HashMap<>();
        Map<String, Integer> giftIndex = new HashMap<>();
        for(String fri : friends){
            myGivenGift.put(fri, new HashMap<>());
            giftIndex.put(fri, 0);
        }
        
        // 누가 누구에게 몇개의 선물을 주었는지, 한 친구의 선물 지수가 몇인지 초기화
        for(String fri: gifts){
            String[] friTm = fri.split(" ");
            giftIndex.put(friTm[0], giftIndex.getOrDefault(friTm[0], 0) + 1);
            giftIndex.put(friTm[1], giftIndex.getOrDefault(friTm[1], 0) - 1);
            
            if(myGivenGift.get(friTm[0]).containsKey(friTm[1])){
                myGivenGift.get(friTm[0]).put(friTm[1], 1 + myGivenGift.get(friTm[0]).get(friTm[1]));
            }else{
                myGivenGift.get(friTm[0]).put(friTm[1], 1);
            }
        }
        // 문제 논리대로 처리
        HashMap<String, Integer> friNextGiftCnt = new HashMap<>();
        HashSet<String> friSet = new HashSet<>();
        for(String fri1 : friends){
            friSet.add(fri1);
            for(String fri2 : friends){
                if(!friSet.contains(fri2)){
                    // 주고받은 선물수가 같다면
                    if((int)myGivenGift.get(fri1).getOrDefault(fri2, 0) == (int)myGivenGift.get(fri2).getOrDefault(fri1,0)){
                        // 선물 지수 비교
                        if((int)giftIndex.get(fri1) > (int)giftIndex.get(fri2)){
                            friNextGiftCnt.put(fri1, friNextGiftCnt.getOrDefault(fri1, 0) + 1);
                        }else if((int)giftIndex.get(fri1) < (int)giftIndex.get(fri2)){
                            friNextGiftCnt.put(fri2, friNextGiftCnt.getOrDefault(fri2, 0) + 1);
                        }
                    // 같지 않다면
                    }else{
                        // 주고받은 선물 수 비교
                        if((int)myGivenGift.get(fri1).getOrDefault(fri2,0) > (int)myGivenGift.get(fri2).getOrDefault(fri1,0)){
                            friNextGiftCnt.put(fri1, friNextGiftCnt.getOrDefault(fri1, 0) + 1);
                        }else{
                            friNextGiftCnt.put(fri2, friNextGiftCnt.getOrDefault(fri2, 0) + 1);
                        }
                    }
                }
            }
        }
        for(Integer i : friNextGiftCnt.values()){
            if(answer < i) answer = i;
        }
        return answer;
    }
}

 

 

 

# 다음달의 선물 여부 결정 알고리즘
#1. 두 사람이 선물을 주고받은 기록이 있고 같지 않은 경우:
#   1-1 이번달 까지 두 사람 사이에 더 많은 선물을 준 사람 선택 -> 뽑힌 사람은 선물하나 받음
#2. 두 사람이 선물을 주고받은 기록이 없거나 같은 경우:
#   2-1 선물 지수가 더 큰 사람 선택 -> 뽑힌 사람은 선물하나 받음
#   2-2 선물 지수마저 같다면 다음달엔 선물 X

# 위 과정을 모두 거치고 다음달에 선물을 가장 많이 받을 사람의 선물 수를 출력
import itertools
def solution(friends, gifts):
    answer = 0
    # 변수 설계 => {사람1 : {사람2 : 횟수, 사람3 : 횟수}}
    myGivenGift = dict()
    giftIndex = dict()
    nextMonthGift = dict()
    for fri1 in friends:
        myGivenGift[fri1] = dict()
        nextMonthGift[fri1] = 0
        giftIndex[fri1] = 0
        for fri2 in friends:
            if fri1 != fri2:
                myGivenGift[fri1][fri2] = 0
                
    for giftGiven in gifts:
        giver, receiver = giftGiven.split(' ')
        myGivenGift[giver][receiver] += 1
        giftIndex[giver] += 1
        giftIndex[receiver] -= 1
        
    traversalList = list(itertools.combinations(friends,2))
    for f1, f2 in traversalList:
        # 두 사람 사이에 선물을 주고받은 기록이 없거나 같은 경우
        if myGivenGift[f1][f2] == myGivenGift[f2][f1]:
            #   2-1 선물 지수가 더 큰 사람 선택 -> 뽑힌 사람은 선물하나 받음
            #   2-2 선물 지수마저 같다면 다음달엔 선물 X
            if giftIndex[f1] > giftIndex[f2]:
                nextMonthGift[f1] += 1
            elif giftIndex[f1] < giftIndex[f2]:
                nextMonthGift[f2] += 1
        # 두 사람 사이에 선물을 주고받은 기록이 있고 같지 않은 경우:
        else:
            #   1-1 이번달 까지 두 사람 사이에 더 많은 선물을 준 사람 선택 -> 뽑힌 사람은 선물하나 받음
            if myGivenGift[f1][f2] > myGivenGift[f2][f1]:
                nextMonthGift[f1] += 1
            elif myGivenGift[f1][f2] < myGivenGift[f2][f1]:
                nextMonthGift[f2] += 1
                
    
    return max(list(nextMonthGift.values()))