[문제]
2007년 KOI에 N명의 학생들이 참가하였다. 경시일 전날인 예비소집일에, 모든 학생들은 자신이 N명 중에서 몇 등을 할 것인지 예상 등수를 적어서 제출하도록 하였다.
KOI 담당조교로 참가한 김진영 조교는 실수로 모든 학생의 프로그램을 날려 버렸다. 1등부터 N등까지 동석차 없이 등수를 매겨야 하는 김 조교는, 어쩔 수 없이 각 사람이 제출한 예상 등수를 바탕으로 임의로 등수를 매기기로 했다.
자신의 등수를 A등으로 예상하였는데 실제 등수가 B등이 될 경우, 이 사람의 불만도는 A와 B의 차이 (|A - B|)로 수치화할 수 있다. 당신은 N명의 사람들의 불만도의 총 합을 최소로 하면서, 학생들의 등수를 매기려고 한다.
각 사람의 예상 등수가 주어졌을 때, 김 조교를 도와 이러한 불만도의 합을 최소로 하는 프로그램을 작성하시오.
[입력]
첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 500,000) 둘째 줄부터 N개의 줄에 걸쳐 각 사람의 예상 등수가 순서대로 주어진다. 예상 등수는 500,000 이하의 자연수이다.
[출력]
첫째 줄에 불만도의 합을 최소로 할 때, 그 불만도를 출력한다.
[입력 예시]
5
1
5
3
1
2
[출력 예시]
3
[내 풀이]
#n=int(input()) #n명(시간 초과 에러)
import sys
n=int(sys.stdin.readline().rstrip())
rank=[] #예상 등수
dissat=0 #불만도
for i in range(n):
rank.append(int(sys.stdin.readline().rstrip()))
rank.sort()
for i in range(n):
#dissat+=rank[i]-(i+1)
dissat+=abs(rank[i]-(i+1))
#print(abs(dissat)) #시간 초과 에러
print(dissat) #불만도 절댓값
[해설]
알고리즘을 생각하는 것 까진 단순한 문제이다.
불만도가 최소가 되어야 하므로, 예상 등수와 실제 등수 사이 차이가 가장 작게끔 만들면 된다.
따라서 (index+1) 과 오름차순으로 정렬된 예상 등수값의 차이를 계산해 절댓값을 누적해 출력했다.
다만 자꾸 시간 초과 오류가 났다. 😢
처음에 고쳐준 곳은 input() 으로 입력 데이터를 받는 부분이다. 이것을 readline() 으로 수정했는데,
그래도 시간 초과 오류가 났다. (알고리즘은 맞는데 도대체 왤까)
두 번째로 바꾸어 준 곳은 rank에 append 해주는 부분이다.
원래는 a 라는 변수에 값을 받고 그 값을 rank로 append 해주도록 만들었는데 수정 이후에는 바로 값이 append 되도록 했다.
그래도 시간 초과 오류가 나길래 마지막으로 수정한 부분은 abs() 를 사용하는 부분이다.
처음엔 값을 모두 계산하고 나서 print 를 해 줄 때 abs() 를 사용했는데 for 문 안에 넣어버렸다.
그랬더니 더이상 시간 초과 오류가 나지 않았다.
계산할 때마다 abs() 로 절댓값을 계산해주어야 하면 이게 시간 초과 위험성이 더 커지는 게 아닌가?
좀 더 생각해 봐야겠다 😭
'알고리즘' 카테고리의 다른 글
순열과 조합 (0) | 2024.05.24 |
---|---|
[프로그래머스] 성격 유형 검사하기 (2) | 2022.11.14 |
[그리디 알고리즘] YONSEI TOTO (0) | 2022.11.09 |
[그리디 알고리즘] Project Teams (0) | 2022.10.10 |
[그리디 알고리즘] 걷기 (0) | 2022.10.10 |