본문 바로가기

알고리즘/Lv. 1

프로그래머스 258712 가장 많이 받은 선물 파이썬 풀이

728x90

난이도 : Lv. 1

풀이일 : 2410292

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


문제


아이디어

  • 이름 대신 숫자를 사용할 수 있도록, 딕셔너리를 활용하자
  • 선물 주고 받은 정보를 2차원 배열에 저장하고, 선물지수는 1차원 배열에 저장하자
  • 주고 받은 선물 개수와 선물지수를 비교하며 각 사람이 받을 선물을 구하자

전체 풀이 코드

def solution(friends, gifts):
    answer = 0
    N = len(friends)
    name = {}
    info = [[0] * N for _ in range(N)]
    index, expect = [0] * N, [0] * N
    
    # 이름 숫자화
    for i in range(N):
        name[friends[i]] = i
    
    # 선물 주고받은 개수, 선물지수 입력 처리
    for gift in gifts:
        g, s = map(str, gift.split())
        info[name[g]][name[s]] += 1
        index[name[g]] += 1
        index[name[s]] -= 1
	
    # 다음 달에 받을 선물 개수 구하기
    for i in range(N):
        for j in range(i + 1, N):
        	# 준 선물이 더 많을 때
            if info[i][j] > info[j][i]:
                expect[i] += 1
            # 받은 선물이 더 많을 때
            elif info[i][j] < info[j][i]:
                expect[j] += 1
            # 선물 개수가 같을 때 선물지수 비교
            else:
                if index[i] > index[j]:
                    expect[i] += 1
                elif index[i] < index[j]:
                    expect[j] += 1
    # 최댓값 저장
    answer = max(expect)
    
    return answer

상세 풀이 코드

def solution(friends, gifts):
    answer = 0
    N = len(friends)
    name = {}
    info = [[0] * N for _ in range(N)]
    index, expect = [0] * N, [0] * N
  • name : 이름 대신 번호를 부여하기 위한 딕셔너리
  • info : 누가 누구에게 선물을 몇 개 줬는지 기록하기 위한 이차원 배열
  • index, expect : 선물지수, 다음달에 받을 선물 개수

 

    for i in range(N):
        name[friends[i]] = i
    
    for gift in gifts:
        g, s = map(str, gift.split())
        info[name[g]][name[s]] += 1
        index[name[g]] += 1
        index[name[s]] -= 1
  • 첫 번째 반복문은 friends를 순회하며 name 딕셔너리에 이름과 번호 쌍을 기록해준다.
  • 두 번째 반복문은 선물 준 사람과 받은 사람 정보 배열을 순회하며, info 배열과 index 배열에 입력처리를 해준다.

 

    for i in range(N):
        for j in range(i + 1, N):
            if info[i][j] > info[j][i]:
                expect[i] += 1
            elif info[i][j] < info[j][i]:
                expect[j] += 1
            else:
                if index[i] > index[j]:
                    expect[i] += 1
                elif index[i] < index[j]:
                    expect[j] += 1
  • 준 선물과 받은 선물을 비교하는 부분
  • 준 선물이 받은 선물보다 많은 경우, 준 사람의 다음 달에 받을 선물을 한 개 더한다.
  • 받은 선물이 준 선물보다 많은 경우, 받은 사람의 다음 달에 받을 선물을 한 개 더한다.
  • 주고 받은 선물의 개수가 같은 경우에는, 선물 지수를 비교하여, 선물지수가 높은 쪽의 다음 달에 받을 선물을 더한다.

 

    answer = max(expect)
    
    return answer
  • answer에 다음 달에 받을 선물 개수 중 가장 큰 값을 저장하고 리턴한다.

느낀점

  • 이중 for문을 작성하면서 조금 헤맸다. 문제가 조금 귀찮게 느껴졌는데, 풀었으니까 이제 다른 언어로 풀어야지