[백준 11000][Greedy] 강의실 배정
그리디 알고리즘을 사용한 이유
- 이거 역시 계획표에 넣을 수 있는 강의 개수 의 최대수를 구하라고 하였으므로 그리디를 생각할만 하다,, 아마도?
백준 11000 강의실 배정
S부터 T까지 진행되는 N개의 수업 중 수강 신청할 수 있는 최대 수업수
실패 코드
# 11000 강의실 배정
# S부터 T까지 진행되는 N개의 수업 중 수강 신청할 수 있는 최대 수업수
# 입력받기
n = int(input())
classes = []
for _ in range(n):
temp = list(map(int, input().split()))
classes.append(temp)
# 정렬순: S -> T 즉, S순으로 정렬 후 수업 진행 시간이 작은 순대로 정렬됨
classes.sort()
standard = 0
cnt = 1
while True:
if standard == n:
break
S = classes[standard][0]
T = classes[standard][1]
for j in range(n):
if standard != j:
if T <= classes[j][0]:
standard += j - 1
cnt += 1
break
standard += 1
print(cnt)
-> 런타임 에러
아마도 RecursionError인 듯 한데,,
우선 이 코드에서 내가 구현하고자 하였던 것은 T보다 크거가 같은 다음 수업(그 수업은 T보다 크거나 같고, 수업 진행시간이 작은 수업임 -> 가능한 최대 수업을 카운트하기 위함)을 다시 standard로 잡아서 다음 가능한 수업의 개수를 세는 식으로 진행하고자 하였다.
이렇게 하게되면 standard가 0인거를 무조건 start로 확정을 짓게 된다. = 그리디 알고리즘에 가장 잘 부합하지 않나? standard를 기준으로 당장 가장 좋은 선택을 하기 때문에?
왜 틀렸지?
실패 코드
일단 위 코드의 문제점
8
1 8
9 16
3 7
8 10
10 14
5 6
6 11
11 12
라고 한다면 standard가 9가 나오기 때문에 break가 안되어서 에러가 났다. -> sol break문을 >= 로 부등호 수정
# 11000 강의실 배정
# S부터 T까지 진행되는 N개의 수업 중 수강 신청할 수 있는 최대 수업수
# 입력받기
n = int(input())
classes = []
for _ in range(n):
temp = list(map(int, input().split()))
classes.append(temp)
# 정렬순: S -> T 즉, S순으로 정렬 후 수업 진행 시간이 작은 순대로 정렬됨
classes.sort()
standard = 0
cnt = 1
while True:
if standard >= n:
break
S = classes[standard][0]
T = classes[standard][1]
for j in range(n):
if standard != j:
if T <= classes[j][0]:
standard += j - 1
cnt += 1
break
standard += 1
print(cnt)
틀렸습니다
로 에러 변경 -> 시간이 너무 오래걸려서 그런가?
실패 코드
# 11000 강의실 배정
# S부터 T까지 진행되는 N개의 수업 중 수강 신청할 수 있는 최대 수업수
# 입력받기
n = int(input())
classes = []
for _ in range(n):
temp = list(map(int, input().split()))
classes.append(temp)
classes.sort()
standard = 0
cnt = 1
while True:
if standard >= n:
break
S = classes[standard][0]
T = classes[standard][1]
# 정렬했으니까 standard부터 시작하도록
for j in range(standard, n):
# if standard != j: -> 그렇게 되면 필요없음
if T <= classes[j][0]:
standard += j - 1
cnt += 1
break
standard += 1
print(cnt)
채점 중(1%)
질문 게시판을 대충 확인해보니까 자료구조의 문제인 것 같기도,,? -> 입력받은 것 중 FIFO 방식으로 pop, push가 되었으면 좋겠으므로 큐를 사용할 예정
실패 코드(큐 변경)
# 11000 강의실 배정
# S부터 T까지 진행되는 N개의 수업 중 수강 신청할 수 있는 최대 수업수
from queue import PriorityQueue # 정렬을 해주어야 되므로 우선순위 큐를 임포트
# 입력받기
n = int(input())
classes = PriorityQueue()
for _ in range(n):
temp = list(map(int, input().split()))
classes.put(temp)
cnt = 1
temp = classes.get()
S = temp[0]
T = temp[1]
while not classes.empty():
compare = classes.get()
if T <= compare[0]:
cnt += 1
S = compare[0]
T = compare[1]
print(cnt)
코드가 많이 짧아지고 단순해지기 했는데, 채점 중(2%)
,,,,,tlqkf
풀이 코드
import heapq
import sys
# 입력받기
input = sys.stdin.readline # 얘의 용도?
n = int(input())
classes = []
for _ in range(n):
temp = list(map(int, input().split()))
classes.append(temp)
# 정렬순: S -> T 즉, S순으로 정렬 후 수업 진행 시간이 작은 순대로 정렬됨
classes.sort()
heap = []
heapq.heappush(heap, classes[0][1]) # 첫 번째 강의가 끝나는 시간을 넣음
for i in range(1, n):
if heap[0] > classes[i][0]:
heapq.heappush(heap, classes[i][1])
if heap[0] <= classes[i][0]:
heapq.heappop(heap)
heapq.heappush(heap, classes[i][1])
print(len(heap))
heap을 사용한 것 이외에는 정렬을 해야되는 것과, 다음 수업 시작시간과의 비교를 통해서 수업 개수를 세는 것은 비슷하다. 하지만 다음 두 개가 차이점이 있다.
❓sys.stdin.readline의 용도
input()은 문자열 변환, 줄 바꿈 제거 등 추가적인 과정이 있고, 데이터가 하나씩 버퍼에 들어가는 반면, sys.stdin.readline()은 문자열로 변환, 줄 바꿈 과정이 없으며 데이터가 한 번에 버퍼에 들어가므로
sys.stdin.readline()이 input()보다 빠르다.
❓정렬을 해야되는데 왜 heap을 사용하였나
heapq 모듈은 왜 빠를까?
PriorityQueue & heapq / 우선순위큐와 힙큐
heap 모듈의 경우는 속도도 빨라서 직접 구현한 힙 클래스로는 시간초과 문제를 해결할 수 있다. 우선순위 큐는 heapq를 활용한 모듈이다. 근데 queue 속 PriorityQueue는 Tread-Safe하고, heapq는 Non-safe하다. 즉, safe한지 아닌지 확인 절차가 필요하므로 속도가 더 느리다.
또한 heapq는 리스트를 힙처럼 사용할 수 있다.
코드 설명
와 미친,,, 실패코드 위쪽 주석을 확인해보면 문제 해석하기 전까지도 문제 이해 잘못함,,,, -> ㅄ,,,,?
수강 신청 할 수 있는 최대의 강의수를 찾는게 아니라 강의실을 최소로 개설하는 것이 문제였다,,,
결국, 끝나는 시간과 시작하는 시간을 비교하는 것은 맞았지만, 경우의 수가 조금 달랐다.
시작하는 순으로 정렬을 했을 때
- 끝나는 시간(heap[0]) <= 시작 시간(classes[i][0]): 기존 강의실에 개설 가능
- 끝나는 시간(heap[0]) > 시작 시간(classes[i][0]): 새로운 강의실 개설 필요
결국 heap[0]은 가장 빨리 끝나는 강의 시간, heap[1], heap[2],,,는 가장 빨리 시작하는 강의 시간의 끝나는 시간이 min-heap 구조로 정렬이 된다.
배운 점
- sys.stdin.readline()
- 문제 똑바로 읽자
- heapq는 빠르다.
골드는 골드다,,,
댓글남기기