본문 바로가기

알고리즘풀이/프로그래머스

[3/29] Kakao Internship 기출문제 풀이

👉 사용 언어 : PYTHON3

가장 많이 받은 선물

✅ Solution

def gift_idx(idx_table, name1, name2):
    if idx_table[name1] < idx_table[name2]:
        return name2
    elif idx_table[name1] > idx_table[name2]:
        return name1
    else:
        return ' '

def solution(friends, gifts):
    max = -1
    idx_name = {i:name for i, name in enumerate(friends)}
    name_idx = {name:i for i, name in enumerate(friends)}
    idx_table = {name:0 for name in friends}
    ans = [0]* len(friends)
    score = [[0] * len(friends) for _ in range(len(friends))]
    for gift in gifts:
        giver, receiver = gift.split()
        score[name_idx[giver]][name_idx[receiver]] += 1
        idx_table[giver] += 1
        idx_table[receiver] -= 1
    for i in range(len(score)):
        for j in range(len(score[i])):
            
            if i != j and score[i][j] > -1 and score[j][i] > -1:
                if score[i][j] < score[j][i]:
                    ans[j] += 1
                elif score[i][j] > score[j][i]:
                    ans[i] += 1
                else:
                    res = gift_idx(idx_table, idx_name[i], idx_name[j])
                    if res != ' ':
                        ans[name_idx[res]] += 1
                score[i][j] = score[j][i] = -1
    return sorted(ans, reverse=True)[0]

 

👉 문제 설명 및 제한 사항

  • 당신의 친구들이 이번 달까지 선물을 주고받은 기록을 바탕으로 다음 달에 누가 선물을 많이 받을지 예측하려고 함
  • 두 사람이 선물을 주고받은 기록이 있다면, 이번 달까지 두 사람 사이에 더 많은 선물을 준 사람이 다음 달에 선물을 하나 받는다.
    • 를 들어 A가 B에게 선물을 5번 줬고, B가 A에게 선물을 3번 줬다면 다음 달엔 A가 B에게 선물을 하나 받는다.
  • 두 사람이 선물을 주고받은 기록이 하나도 없거나 주고받은 수가 같다면, 선물 지수가 더 큰 사람이 선물 지수가 더 작은 사람에게 선물을 하나 받는다.
    • 선물 지수 : 이번 달까지 자신이 친구들에게 준 선물의 수에서 받은 선물의 수를 뺀 값
    • 를 들어 A가 친구들에게 준 선물이 3개고 받은 선물이 10개라면 A의 선물 지수는 -7이다. B가 친구들에게 준 선물이 3개고 받은 선물이 2개라면 B의 선물 지수는 1이다. 만약 A와 B가 선물을 주고받은 적이 없거나 정확히 같은 수로 선물을 주고받았다면, 다음 달엔 B가 A에게 선물을 하나 받는다.
    • 만약 두 사람의 선물 지수도 같다면 다음 달에 선물을 주고받지 않는다.
  • 매개변수 : 친구들의 이름을 담은 1차원 문자열 배열 friends, 이번 달까지 친구들이 주고받은 선물 기록을 담은 1차원 문자열 배열 gifts
    • 2 ≤ friends의 길이 = 친구들의 수 ≤ 50
    • friends의 원소 : 친구의 이름을 의미하는 알파벳 소문자로 이루어진 길이가 10 이하인 문자열
    • 동명이인 X
  • 리턴값 : 다음달에 가장 많은 선물을 받는 친구가 받을 선물의 수
    • 1 ≤ gifts의 길이 ≤ 10,000
    • gifts의 원소 : "A B"형태의 문자열
      • A : 선물을 준 친구의 이름 / B : 선물을 받은 친구의 이름
      • A와 B : friends의 원소
      • A와 B가 같은 이름인 경우는 존재X

👉 아이디어

  • idx:name 형태와 name:idx 형태의 딕셔너리 2개를 생성한다. (= idx_name, name_idx)
  • 선물 지수를 계산하기 위한 name:선물 지수 형태의 딕셔너리도 생성한다. (= idx_table)
  • 정답 배열과 [준 사람 idx][받은 사람 idx]로 이루어진 2차원 배열도 생성한다. (= ans, score)
  • 반복문을 돌려 서로 주고 받은 선물 개수에 대해 scrore 배열에 값을 저장하고, idx_table선물 지수를 계산한다.
    • 선물 지수 : giver+1 / receiver-1
  • score에서 중첩 반복문을 돌려 준 사람과 받은 사람의 선물 수 비교 결과에 따라 실행문을 다르게 작성한다.
    • ans 배열에서 받은 선물이 더 적은 사람의 idx에 +1 한다.
    • 만약 같으면, 선물 지수가 더 큰 사람의 idx에 +1 한다.
    • 확인한 score 배열의 원소는 -1로 바꿔준다. (= 중복 체크방지하기 위해❗️)
  • ans 배열의 원소를 내림차순 정렬한 후, 맨 앞 원소를 리턴한다.

'알고리즘풀이 > 프로그래머스' 카테고리의 다른 글

[Lv2.] 스택/큐 - 올바른 괄호  (0) 2024.04.01
[Lv2.] 힙 - 더 맵게  (0) 2024.03.27
[Lv2.] 덧칠하기  (0) 2024.03.20
[Lv2.] 정렬 - H-Index  (0) 2024.03.19
[Lv2.] 정렬 - 가장 큰 수  (0) 2024.03.16