https://softeer.ai/practice/info.do?idx=1&eid=1309
현주는 N명의 인원이 참여하는 프로그래밍 스터디 그룹을 이끌고 있다.
현주는 스터디를 위해 대회를 세 개 개최하였고, 모든 구성원이 각 대회에 참여하였다. 참가자는 각 대회에서 0 이상 1,000 이하의 정수인 점수를 얻는다. 한 대회에서 둘 이상의 참가자가 동점이 나오는 경우도 있을 수 있다.
현주는 각 대회별 등수 및 최종 등수를 매기고 싶다. 등수는 가장 점수가 높은 사람부터 1등, 2등, ···, N등의 순서대로 붙는다. 만일 동점이 있을 경우 가능한 높은 (등수의 수가 작은) 등수를 부여한다. 즉, 점수가 내림차순으로 10,7,6,6,4의 순서일 경우, 6점을 받은 두 사람은 공동 3등이 되고, 그 다음 순서인 4점을 받은 사람은 5등이 된다. 이 규칙을 다르게 표현하면 다음과 같다: 각 사람마다 “나보다 점수가 큰 사람”의 수를 세어 1을 더한 것이 자신의 등수가 된다. 대회별 등수는 각 대회에서 얻은 점수를 기준으로 하며 최종 등수는 세 대회의 점수의 합을 기준으로 한다.
각 참가자의 대회별 등수 및 최종 등수를 출력하는 프로그램을 작성하시오.
3 ≤ N ≤ 100,000
첫째 줄에 참가자의 수를 나타내는 정수 N이 주어진다.
이어 세 개의 줄에 각 대회의 결과를 나타내는 N개의 정수가 주어진다. 이중 i번째 정수는 그 대회에서 i번째 사람이 얻은 점수를 의미한다.
첫 세 개의 줄에는 각 참가자의 대회별 등수를 출력한다. 즉 이중 c번째 줄의 i번째 정수는 c번째 대회에서의 i번째 사람의 등수를 의미한다.
이어 새로운 줄에 같은 형식으로 각 참가자의 최종 등수를 출력한다.
이번 문제는 3라운드에 걸쳐 시합을 진행하고 각 라운드 별 등수를 정하고 라운드 총점에 대한 등수도 출력하는 문제이다.
등수를 저장할 리스트를 2차원 배열로 만드는데 총 3라운드만 진행하니 row를 4로 맞추어 준다. 그리고 나서 각 row를 순회하는데 시작 전에 defaultdict를 통해 해당 점수에 대한 인덱스의 값을 저장할 수 있도록 한다. 이는 동점자를 해결하기 위해서이다.
그리고 각 선수의 점수를 마지막 row에 더해주면서 총점에 대한 등수를 측정할 수 있게 해준다. 이후에 저장한 defaultdict를 점수에 짜라 내림차순으로 정렬해주고 등수를 매겨준다.
해당 점수에 저장된 인덱스에는 같은 등수를 배정해주고 동점자 수에 대한 값을 측정 해준다. 등수 배정이 완료된 후 동점자 수만큼 등수를 올려주어 등수에 대한 혼란을 방지 해준다.
문제 자체는 DP로 푸는 것 같고 생각보다 쉬운 문제였다. 아래 코드를 보자.
import sys
from collections import defaultdict
input = sys.stdin.readline
n = int(input())
# 각 라운드 리스트에 총점에 대한 row를 추가 해주고 socre보드를 만들어준다.
boards = [list(map(int, input().split())) for _ in range(3)]
boards.append([0 for _ in range(n)])
scores = [[0 for _ in range(n)] for _ in range(4)]
# 각 라운드를 돌면서 총점을 업데이트 해주고 등수를 측정한다.
for row in range(4):
tmp = defaultdict(list) # 각 점수를 받은 사람을 저장할 dict
for col in range(n):
if row < 3: # 총점을 더해주는 조건문
boards[3][col] += boards[row][col]
tmp[boards[row][col]].append(col) # 해당 점수에 인덱스를 저장해준다.
# 점수를 내림차순으로 해주고 등수를 지정해줄 변수를 만들어준다.
keyval = sorted(list(tmp.keys()), reverse=True)
rank = 1
# 각 점수에 들어간 인덱스에 등수를 할당해주고 동점자(t) 수를 측정하여 동점에 대한 등수 산정을 쉽게 해준다.
for idx in range(len(keyval)):
t = 0
for value in tmp[keyval[idx]]:
scores[row][value] = rank
t += 1
rank += t
for score in scores:
print(*score)
커피 한 잔은 유익한 게시글을 쓰는데 큰 힘이 됩니다.
'IT 톺아보기 > 알고리즘' 카테고리의 다른 글
백준 11054번 가장 긴 바이토닉 부분 수열 | python (0) | 2023.02.03 |
---|---|
백준 24060번 알고리즘 수업 - 병합 정렬 1 | python (0) | 2023.01.29 |
백준 24479번 알고리즘 수업 - 깊이 우선 탐색 1 | python (0) | 2023.01.26 |
소프티어(softeer) [인증평가(5차) 기출] 업무 처리 | python (0) | 2023.01.26 |
백준 2470번 두 용액 | python (0) | 2023.01.25 |