문제
https://www.acmicpc.net/problem/10989
카운팅 정렬로 숫자 정렬하는 문제. 그러나 이 문제에는 함정카드가 하나 있다. (대충 함정좌 짤)
메모리 제한이 8MB밖에 안된다. 자바랑 코틀린만 많이 준다.
Reference
https://seongonion.tistory.com/130
https://www.acmicpc.net/board/view/26132
https://scarlett-choi.tistory.com/9
풀이
문제를 보면 아시겠지만 이전의 정렬 문제와 달리 숫자가 중복이 된다. 우리야 숫자 같으니까 똑같이 두지 뭐 하지만 컴퓨터는 이게 뭐여 하면서 밥상뒤집기를 시전할 수도 있다. 그래서 이럴 때 필요한 게 카운팅 정렬임… 함정 얘기는 이따가 해드릴게여.
a = [1, 2, 6, 5, 6, 6, 4, 3, 3, 4, 2]
def count_sort(arr):
m = max(arr)
# 최댓값 도출
C = [0] * (m + 1)
# Counting Array 생성
for a in arr:
C[a] += 1
print("Counting Array: {}".format(C))
# counting Array에 채워넣는다
for i in range(1, m + 1):
C[i] += C[i - 1]
print("Array's Sum: {}".format(C))
# 누적합으로 바꾼다
result = [0] * len(arr)
# 정렬을 위한 배열
for a in arr:
result[C[a] - 1] = a
C[a] -= 1
print("Sorting... :{}".format(result))
# 정렬 콜
return result
print(count_sort(a))
이게 카운팅 정렬의 코드이다. 뭐야 최댓값이 왜 나와요 저 배열 뭔데요…
카운팅 정렬이 진행되는 과정에서는 배열이 두 개 필요하다. 첫번째가 Counting Array, 두번째는 결과를 만들기 위한 배열이다. Counting Array는 말 그대로 이 배열에 어떤 원소가 몇 개 있느냐를 표시하기 위한 배열로, 배열 전체를 돌면서 원소를 세고 있을때마다 카운트를 하나씩 올리는 방식이다. 이렇게 배열 내 원소를 전부 셌다면, 그 다음은 누적합(개수의 누적합)을 구해 배열화하게 된다. 근데 이것만 하면 정렬이 되나요? 된다.
누적합 배열을 통해 개수를 유추할 수 있으니, 어디에서 어디까지 어떤 원소가 들어가게 되는 지 알 수 있기 때문에 알아서 채우면 된다.
그럼 저거 내면 되나요?
메모리 초과: YOU JUST ACTIVATED MY TRAP CARD (브금은 셀프)
위에서 자바랑 코틀린 말고 메모리가 8메가라고 했는데, 저거 일일이 받아서 배열에 저장하면 초과 뜬다.
import sys
N = int(sys.stdin.readline())
array = [0] * 10001
for i in range(N):
input_num = int(sys.stdin.readline())
array[input_num] = array[input_num] + 1
for i in range(10001):
if array[i] != 0:
for j in range(array[i]):
print(i)
그래서 이거 내야됨. 아닛 이 짤막한 코드로 된다고? ㅇㅇ 됨 내가 봤음.
위에서 카운팅 정렬은 입력받은 배열에서 세기 위한 배열과 결과를 저장할 배열 두 개를 만든다고 했는데, 요 작고 소듕한 코드는 그 만드는 과정을 생략해버렸다.
그래서 만드는 배열은 0이 10001개인 배열 하나뿐이고, 숫자가 입력될때마다 배열의 입력받은 값에 해당하는 인덱스의 숫자를 하나 추가한다. 이게 뭔 소리냐면 배열이 다 0이고 입력값이 7이면 배열[7]을 0에서 1로 바꾼다는 얘기. 그리고 배열을 싹 돌아서 안에 0이 아닌 숫자가 있으면 그만큼 해당 숫자를 출력한다.
'BOJ > [BOJ] Python' 카테고리의 다른 글
백준 2108번 풀이 (0) | 2022.08.23 |
---|---|
백준 25305번 풀이 (0) | 2022.08.23 |
백준 2750번 풀이 (0) | 2022.08.20 |
백준 1436번 풀이 (0) | 2022.08.20 |
백준 1018번 풀이 (0) | 2022.08.20 |