[SWEA] 1983 조교의 성적 매기기
이 문제는 모든 학생들의 성적을 줄 세우고, 특정 학생의 성적을 반환할 수 있어야 한다. 모든 학생들에게 제한된 수의 각 학점을 부여하기 위해서 수식을 작성할수도 있겠지만, 직관적으로 부여할 수 있는 모든 학점을 list로 작성하여 학생의 성적 순서에 따라서 A+
부터 D0
까지의 학점을 부여할 수 있도록 작성해보았다.
모든 학생들에게 성적을 부여하는 것이 아닌, 순위로부터 성적을 매길 수 있는 방법을 택한다면 메모리 측면에서 더 효율적일 수 있겠다.
나의 풀이
# 테스트케이스 수
t = int(input())
# 각 테스트 케이스의 값은 answer에 저장
answer = []
for _ in range(t):
n, k = map(int, input().split())
max = n // 10 # 부여할 수 있는 grade별 갯수
# 낮은 등급부터 grades 배열에 모두 저장
grades=[]
for i in range(10):
for j in range(max):
grades.append('D0')
for j in range(max):
grades.append('C-')
for j in range(max):
grades.append('C0')
for j in range(max):
grades.append('C+')
for j in range(max):
grades.append('B-')
for j in range(max):
grades.append('B0')
for j in range(max):
grades.append('B+')
for j in range(max):
grades.append('A-')
for j in range(max):
grades.append('A0')
for j in range(max):
grades.append('A+')
# 학생별 점수 배열을 students 저장
students = [list(map(int, input().split())) for _ in range(n)]
# 학생별 환산 점수와 학생 번호를 순서쌍으로 scores에 저장
scores = []
for i in range(n):
scores.append((students[i][0]*0.35+students[i][1]*0.45+students[i][2]*0.2, i+1))
scores.sort(reverse=True) #환산 점수를 기준으로 내림차순 정렬 (순서쌍 첫 번째가 기준값임, 같을 시 두 번째 값 비교)
# 정렬된 scores 배열을 순회하면서 테스트케이스의 학생 번호와 일치하는 값이 나오면 answer에 grade를 삽입하고 반복문 종료
for i in range(n):
if scores[i][1] == k:
answer.append(grades.pop())
break
else:
grades.pop()
for i in range(t):
print(f"#{i+1} {answer[i]}")
2022.05.26 다시 풀이
for tc in range(1, int(input())+1):
n, k = map(int, input().split()) # n = 총 학생 수, k = 점수 알고 싶은 학생 번호
student = list(range(0,n+1))
score = [0]
grade = ['D0', 'C-', 'C0', 'C+', 'B-', 'B0', 'B+', 'A-', 'A0', 'A+']
k_rank = 0
for i in range(n):
mid, fin, assi = map(int, input().split())
score.append(mid*0.35 + fin * 0.45 + assi * 0.2)
_dict = dict(zip(student, score))
sorted_dict = sorted(_dict.items(), key=lambda item: item[1], reverse=True)
for i in range(len(sorted_dict)):
if sorted_dict[i][0] == k:
k_rank = i+1
step = n//10
for i in range(step,n+1,step):
result = grade.pop()
if k_rank <= i:
break
print(f"#{tc}",result)
저번에 작성한 로직보다는 훨씬 깔끔해진 것 같다.. 특히 모든 grade를 저장했던 부분은 비효율의 끝판왕이었던 것 같다…
이번에는 dictionary를 이용해서 학생들을 줄 세우고 k 번째 학생의 랭킹을 구하고
각 등급에 속할 수 있는 인원수 만큼을 건너 뛰면서 grade를 pop하는데, k 학생의 랭킹이 속한 범위에서 반복문을 멈추고 해당 grade를 출력할 수 있도록 했다.
- 학생들 총점 구하기
- 학생 등수 구하기 (1등 부터 시작이기 때문에 Index 조심)
- 학생이 어떤 구간에 속하는지 파악(n//10) → 학점 출력
좀 더 단순화 하고 싶었는데 이정도에 그쳤다.
딕셔너리 자료형을 sorting할 때 애 먹을 것 같아서 한 번 정리했다.
dict sort
dict = {'0':1, '3':2, '1':3}
print(dict) # {'0': 1, '3': 2, '1': 3}
print(sorted(dict)) # ['0', '1', '3']
dict.items()를 활용해서 정렬하지 않으면 key값으로만 정렬하고 값을 반환함.
Key로 정렬
dict = {'0':1, '3':2, '1':3}
print(dict.items()) # dict_items([('0', 1), ('3', 2), ('1', 3)])
print(sorted(dict.items())) # [('0', 1), ('1', 3), ('3', 2)]
Value로 정렬
오름, 내림 차순은 reverse=True 명시해주면 됨
dict = {'0':1, '3':2, '1':3}
print(sorted(dict.items(), key=lambda item:item[1])) # [('0', 1), ('3', 2), ('1', 3)]