CodingTest/Baekjoon

[baekjoon] 백준 2012번(파이썬): 등수 매기기

JunJangE 2021. 6. 14. 21:01

문제

 

2012번: 등수 매기기

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 500,000) 둘째 줄부터 N개의 줄에 걸쳐 각 사람의 예상 등수가 순서대로 주어진다. 예상 등수는 500,000 이하의 자연수이다.

www.acmicpc.net

- 모든 학생들은 자신이 N명 중에서 몇 등을 할 것인지 예상 등수를 적어서 제출하도록 하였다.

- 조교는 실수로 모든 학생의 프로그램을 날려 버렸다.

- 1등부터 N 등까지 동석차 없이 등수를 매겨야 하는 김 조교는, 어쩔 수 없이 각 사람이 제출한 예상 등수를 바탕으로 임의로 등수를 매기기로 했다.

- 자신의 등수를 A 등으로 예상하였는데 실제 등수가 B 등이 될 경우, 이 사람의 불만도는 A와 B의 차이 (|A - B|)로 수치화할 수 있다.

- 당신은 N명의 사람들의 불만도의 총합을 최소로 하면서, 학생들의 등수를 매기려고 한다.

- 각 사람의 예상 등수가 주어졌을 때, 김 조교를 도와 이러한 불만도의 최소합을 구하는 문제이다.

- 학생 수 N이 주어진다. (1 ≤ N ≤ 500,000)

- N개의 줄에 걸쳐 각 사람의 예상 등수가 순서대로 주어진다. 예상 등수는 500,000 이하의 자연수이다.

알고리즘

- 학생의 수를 입력받는다.

- 각 학생이 예상한 등수를 입력받아 리스트 변수에 넣는다.

- 각 학생이 예상한 등수를 오름참순으로 정렬한다.

- 학생의 수만큼 반복하여 1등부터 n등까지 랭크를 만든다.

- 랭크에서 각 학생이 예상한 등수를 빼줘 불만도에 최소를 구한다.

- 불만도를 다 더해주어 출력한다.

코드

import sys

n = int(sys.stdin.readline())
ex = [int(sys.stdin.readline()) for x in range(n)]
# 각 사람이 예상한 등수를 오름차순으로 정렬한다.
ex.sort()
# 랭크를 사람의 수만큼 만든다.
rank = [i for i in range(1, n+1)]
# 불만도 최소합
result = 0

# 랭크에서 각 사람이 예상한 등수를 빼면 불만도에 최소를 구할수있다.
for i in range(n):
    result += abs(rank[i] - ex[i])

print(result)

결과

위 코드에서 각 사람이 예상한 등수를 오름차순으로 정렬시킨 이유는 각 사람이 예상한 등수와 랭크를 가깝게 형성시켜 불만도에 최소를 구하기 위해서이다. 따라서 랭크에서 각 사람이 예상한 등수를 뺐을 때 불만도가 최소가 나오게 되는 것이다. 오름차순으로 정렬한 결과가 자신이 예상한 등수가 아니더라도 오름차순으로 정렬했기 때문에 예상한 등수와 큰 차이가 없는 랭크를 받게 된다. 결과적으로 불만도의 최소를 각 사람별로 더해주면 문제를 해결할 수 있게 된다.

불만도에 최소를 구하는 과정에서 abs() 함수를 사용하게 되는데 abs() 함수는 절댓값을 구할 때 사용하는 함수로 랭크와 자신이 예상한 등수에 차이를 구하기 위해서 사용되었다.

github

 

junjange/CodingTest

내가 푼 코딩 테스트 문제와 해결법. Contribute to junjange/CodingTest development by creating an account on GitHub.

github.com