➰ 10825번 국영수
▪ 문제
도현이네 반 학생 N명의 이름과 국어, 영어, 수학 점수가 주어진다. 이때, 다음과 같은 조건으로 학생의 성적을 정렬하는 프로그램을 작성하시오.
- 국어 점수가 감소하는 순서로
- 국어 점수가 같으면 영어 점수가 증가하는 순서로
- 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로
- 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 (단, 아스키 코드에서 대문자는 소문자보다 작으므로 사전순으로 앞에 온다.)
▪ 입력
첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 100보다 작거나 같은 자연수이다. 이름은 알파벳 대소문자로 이루어진 문자열이고, 길이는 10자리를 넘지 않는다.
▪ 출력
문제에 나와있는 정렬 기준으로 정렬한 후 첫째 줄부터 N개의 줄에 걸쳐 각 학생의 이름을 출력한다.
💡 구현 아이디어
정렬 알고리즘은 버블 정렬, 합병 정렬, 퀵 정렬 등 종류가 다양하다.
하지만 파이썬으로 코딩테스트에서 정렬 문제를 푼다고 했을 때 대부분은 구현할 필요 없이 그냥 sort() 함수를 사용하면 해결된다. 특히 sort() 함수에서 key 인자를 사용하는 방법을 꼭 알아야 한다. 이곳에 관련 개념을 간단하게 정리해 놓았다.
풀이는 다음과 같다.
1) 각 학생의 이름, 국어, 영어, 수학 점수를 리스트에 튜플 형태로 한 묶음씩 입력받고,
2) key=lambda x를 사용하여 정렬 부분을 한 줄로 구현했다. (갓이썬!!!) 이때 정렬 기준이 오름차순, 내림차순으로 다양한데 -를 이용해서 해결했다. sort(key=lambda x: x[0]))이라고 했을 때 x[0]을 기준으로 오름차순으로 정렬된다. default는 오름차순이므로 -x[0]으로 했을 때 내림차순으로 정렬된다.
이를 소스코드로 구현하면 다음과 같다. 오히려 이 문제는 정렬하는 부분보다 입력받는 부분을 어떻게 더 깔끔하게 작성할지 고민해야 할 것 같다.
💻 소스 코드
# 정렬
# 국영수
import sys
input = sys.stdin.readline
# 입력 받기
N = int(input())
name = [''] * N
kor = [0] * N
eng = [0] * N
math = [0] * N
for i in range(N):
name[i], kor[i], eng[i], math[i] = input().split()
(kor[i], eng[i], math[i]) = map(int, (kor[i], eng[i], math[i]))
li = [(name[i], kor[i], eng[i], math[i]) for i in range(N)]
# 정렬하기
li.sort(key = lambda x: (-x[1], x[2], -x[3], x[0]))
# 출력하기
for i in range(N):
print(li[i][0])
'Algorithm' 카테고리의 다른 글
[백준/파이썬] 2108 통계학 - 수학, 구현, 정렬 (0) | 2022.09.25 |
---|---|
[백준/파이썬] 2751 수 정렬하기2 - 합병 정렬 구현하기 (0) | 2022.09.25 |
[백준/파이썬] 2839 설탕 배달 - 다이나믹 프로그래밍 (1) | 2022.08.30 |
[백준/파이썬] 1300 K번째 수 - 이진 탐색 (0) | 2022.08.30 |
[백준/파이썬] 1051 정사각형 - 구현 (0) | 2022.07.25 |