https://www.acmicpc.net/problem/3020
문제정리
동굴 길이 N , 높이 H
석순, 종유석 ( 아래, 위 ) 순서로 장애물의 길이가 입력된다.
임의의 높이로 일직선을 그을 때 만나는 장애물의 수가 가장 적은 높이를 출력
문제풀이
먼저 가장 쉽게 생각해보자
모든 H 에 대해서 arr[N] 를 처음부터 끝까지 확인해서 석순은 H 보다 낮은 원소의 개수를, 종유석은 H 보다 높은 원소의 개수를 구하면 된다. 즉 시간은 모든 H 에 관해 arr[N] 배열의 확인을 하면 되므로 O(NH) 이다.
이 방법은 20만*40만이라 시간초과가 난다. 어떻게 줄일 수 있을 지 확인해보자
모든 H 에 관해 판단을 해야하는 것은 당연하다. -> 그래야 최소로 부딪히는 H 를 구하쥬
그렇다면 반복적으로 arr[N] 배열을 확인 하는 것을 줄여야 한다.
우리가 H 마다 계산하는 H 보다 작은 arr[N] 원소의 개수를 미리 bottom[H] 에 구해놓으면 된다.
bottom[7] = arr[7]
bottom[6] = bottom[7] + arr[6]
...
bottom[1] = bottom[2] + arr[1]
이를 종유석, 석순에 대해 짜주면
import sys
input = sys.stdin.readline
from collections import Counter
N, H = map(int, input().split())
top = [0] * (H + 1) # 종유석
bottom = [0] * (H + 1) # 석순
for i in range(N):
num = int(input())
if i % 2 == 0: # 짝수, 아래, 석순
bottom[num] += 1
else:
top[num] += 1
Px, Py = [0]* (H + 1), [0] * (H + 1)
Px[H], Py[1] = top[H], bottom[H]
for r in range(1,H):
Px[H-r] = Px[H-r+1] + top[H-r]
Py[r+1] = Py[r] + bottom[H-r]
P = [ 0 for _ in range(H)]
for r in range(H):
P[r] = Px[r+1] + Py[r+1]
c = Counter(P)
minXY = list(sorted(c.keys()))[0]
print(minXY, c[minXY])
참고 : https://deveun.tistory.com/entry/Python%EB%B0%B1%EC%A4%80-3020%EA%B0%9C%EB%98%A5%EB%B2%8C%EB%A0%88
'코딩 농장 > 백준 문제' 카테고리의 다른 글
[백준 Python] 2110 공유기 설치 (0) | 2022.05.23 |
---|---|
[백준 Python] 1072번 게임 (0) | 2022.05.23 |
[백준 Python] 2512번 예산 (0) | 2022.05.23 |
[백준 Python] 15975번 화살표 그리기 (0) | 2022.05.22 |
[백준 Python] 1431번 시리얼 번호 (0) | 2022.05.22 |