문제
https://school.programmers.co.kr/learn/courses/30/lessons/258712?language=python3#
해설
이 문제의 경우 문제에서 요구하는 내용들(테이블 만들기, 테이블 각각의 값 계산 후 집어넣기)을 하나하나 코드로 구현하고, 마지막에 조건대로 코드를 작성하면 쉽게 풀 수 있다.
table_1 = [[0 for _ in range(len(friends))] for _ in range(len(friends))]
table_2 = [[0 for _ in range(3)] for _ in range(len(friends))]
이를 위해 가장 먼저 주고 받은 선물 갯수를 기록하는 첫번째 테이블과, 주고 받은 선물의 갯수 및 선물 지수를 기록하는 두번째 테이블을 만들어준다. 첫번째 테이블의 경우 "친구의 수* 친구의 수"의 크기로 구성된 테이블이며, 두번째 테이블의 경우 "친구의 수*3"의 크기로 구성된 테이블이다.
present_cnts = [0 for _ in range(len(friends))]
테이블을 만들어주었으니, 이제 각각의 친구들이 다음 달에 받을 선물을 기록할 리스트도 하나 만들어준다.
for i in range(len(gifts)):
giver, taker = gifts[i].split()
table_1[friends.index(giver)][friends.index(taker)] += 1
for i in range(len(table_1)):
table_2[i][0] = sum(table_1[i])
for j in range(len(table_1[0])):
table_2[i][1] += table_1[j][i]
table_2[i][2] = table_2[i][0] - table_2[i][1]
이제 필요한 변수들은 모두 준비가 되었으니, 첫번째 테이블과 두번째 테이블에 해당되는 값들을 하나하나 넣어준다. 선물을 주고 받은 목록(gifts)에서 주는 사람과 받는 사람의 이름을 따로따로 받아들이고, 주는 사람과 받은 사람의 인덱스를 찾은 후 선물을 준 갯수를 하나하나 계산해주어 첫번째 테이블에 저장해준다.
그리고 나서 첫번째 테이블을 기반으로 두번째 테이블을 계산해준다. 여기서 주목할 점은 첫번째 테이블의 i번째 행 값의 총합은 결국 i번째 사람이 준 선물의 총 갯수이고, i번째 열 값의 총합은 i번째 사람이 받은 선물의 총 갯수가 된다.
이를 토대로 table_2에서 준 갯수, 받은 갯수를 각각 기입해주고, 준 갯수와 받은 갯수의 차로 선물지수를 계산해준다.
for i in range(len(friends)):
for j in range(i+1,len(friends)):
# i가 더 많이 줌
if (table_1[i][j]>table_1[j][i]):
present_cnts[i] += 1
# i가 더 많이 받음
elif (table_1[i][j]<table_1[j][i]):
present_cnts[j] += 1
# 똑같음 - 선물지수 비교
elif ((table_1[i][j]==table_1[j][i])):
if (table_2[i][2]>table_2[j][2]):
present_cnts[i] += 1
elif (table_2[i][2]<table_2[j][2]):
present_cnts[j] += 1
answer = max(present_cnts)
return answer
마지막으로 i번째 친구와 j번째 친구를 비교하여 주고 받은 선물의 갯수가 더 많고 적은지에 따라 i에게 선물을 주거나 또는 j에게 선물을 주도록 처리한다. 그리고 만약 i와 j가 주고 받은 선물의 갯수가 동일할 경우에는 선물 지수를 비교하는 그 다음 조건문으로 넘어가서, 선물 지수의 크고 적음에 따라 선물을 주도록 처리한다.
그리고 마지막으로 가장 선물을 많이 받은 갯수를 answer에 저장해주고 리턴해주면 끝난다.
코드
def solution(friends, gifts):
answer = 0
present_cnts = [0 for _ in range(len(friends))]
# 준사람 받은사람 테이블 만들기 -> table_1
table_1 = [[0 for _ in range(len(friends))] for _ in range(len(friends))]
# 선물지수 계산 테이블 만들기 -> table_2
table_2 = [[0 for _ in range(3)] for _ in range(len(friends))]
# 주고 받은 리스트 처리
for i in range(len(gifts)):
# 받은 사람, 준 사람 저장
giver, taker = gifts[i].split()
# 준사람 받은사람 테이블에 선물 주고받은 기록 남기기
table_1[friends.index(giver)][friends.index(taker)] += 1
# 준사람 받은사람 테이블 기준으로 선물지수 계산하기
for i in range(len(table_1)):
# i가 준 선물 갯수 계산 및 저장
table_2[i][0] = sum(table_1[i])
# i가 받은 선물 갯수 계산 및 저장
for j in range(len(table_1[0])):
table_2[i][1] += table_1[j][i]
# 준 갯수 받은 갯수 토대로 선물지수 계산
table_2[i][2] = table_2[i][0] - table_2[i][1]
# 다음달에 받을 선물 예측 시작
for i in range(len(friends)):
for j in range(i+1,len(friends)):
# i가 더 많이 줌 -> i가 선물 받음
if (table_1[i][j]>table_1[j][i]):
present_cnts[i] += 1
# i가 더 많이 받음 -> i가 j에게 선물 줌
elif (table_1[i][j]<table_1[j][i]):
present_cnts[j] += 1
# 똑같음 - 더 나아가 선물지수 비교
elif ((table_1[i][j]==table_1[j][i])):
# i의 선물지수가 j보다 높음
if (table_2[i][2]>table_2[j][2]):
# i가 선물 받음
present_cnts[i] += 1
# j의 선물지수가 i보다 높음
elif (table_2[i][2]<table_2[j][2]):
# j가 선물 받음
present_cnts[j] += 1
# 최대로 받은 선물 갯수 저장 및 출력
answer = max(present_cnts)
return answer
결과
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[파이썬] 프로그래머 알고리즘 고득점 Kit - 해시 / 완주하지 못한 선수 완벽해설 (0) | 2024.05.09 |
---|---|
[파이썬] 프로그래머 알고리즘 고득점 Kit - 해시 / 폰켓몬 완벽해설 (0) | 2024.05.09 |
[파이썬] 프로그래머 코딩테스트 - 피보나치 수 완벽해설 (효율성 고려) (0) | 2024.05.05 |
[파이썬] 프로그래머스 코딩테스트 입문 - 다음에 올 숫자 완벽해설 (0) | 2024.04.20 |
[파이썬] 프로그래머스 코딩테스트 입문 - 옹알이 (1) 완벽해설 (0) | 2024.04.19 |