🧩 Problem Solving/[λ°±μ€€]

[λ°±μ€€] 28018 μ‹œκ°„μ΄ 겹칠까?(feat.imos법) (python 파이썬)

μ œλ΄‰μ•„ 2023. 7. 18. 00:24

https://www.acmicpc.net/problem/28018

 

28018번: μ‹œκ°„μ΄ 겹칠까?

λŒ“κΈ€μ„ 달아쀀 학생 수 $N$이 μ£Όμ–΄μ§„λ‹€. $(1\leq N\leq 100\,000)$ λ‹€μŒ $N$개 μ€„μ—λŠ” 각 ν•™μƒμ˜ μ’Œμ„ λ°°μ • μ‹œκ° $S$와 μ’…λ£Œ μ‹œκ° $E$κ°€ μ£Όμ–΄μ§„λ‹€. $(1\leq S\leq E\leq 1\,000\,000)$ λ‹€μŒ μ€„μ—λŠ” νŠΉμ •ν•œ μ‹œκ°μ˜ 개수

www.acmicpc.net


λŒ€νšŒμ—μ„œ ν•΄κ²° λͺ»ν•˜κ³  λλ‚˜κ³  ν•΄κ²°ν•œ 문제. 처음 λ“£λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄μ–΄μ„œ μ‹ κΈ°ν–ˆλ‹€.(λˆ„μ ν•© μ•Œκ³ λ¦¬μ¦˜ κ°™λ‹€)

아직도 λͺ¨λ₯΄λŠ”κ²Œ λ§Žμ€κ±° κ°™λ‹€, λ°°μ›€μ—λŠ” 끝이 μ—†λŠ” κ±° κ°™λ‹€.


아이디어

문제λ₯Ό 보고 μ‹œκ°„μ œν•œμ„ κ³ λ €ν•˜μ§€μ•ŠμœΌλ©΄ 정말 μ‰¬μš΄ λ‚œμ΄λ„λ‹€. ν•˜μ§€λ§Œ μž…λ ₯값이 크기 λ•Œλ¬Έμ— μ‹œκ°„ 고민을 해봐야 λœλ‹€.

 

이 아이디어λ₯Ό μ‰½κ²Œ λ§ν•˜λ©΄, λ“€μ–΄μ˜€κ³  λ‚˜κ°€λŠ” μ‹œκ°„λ§Œ μ €μž₯ν•˜λ©΄ λœλ‹€.  

 

λ¨Όμ € μ΅œλŒ€ μ‹œκ°„(1000000) 크기의 1차원 리슀트λ₯Ό μ„ μ–Έν•˜κ³  값을 0으둜 μ΄ˆκΈ°ν™”ν•΄ μ€€λ‹€. 그리고 μž…μž₯ μ‹œκ°„, 퇴μž₯ μ‹œκ°„μ— 맞게 +1을 ν•΄μ€€λ‹€. 

예제 1 같은 경우 λ‹€μŒκ³Ό κ°™λ‹€.

in_time = [0, 1, 1, 0, 0,...]

out_time = [0, 0, 0, 1, 1,...]

 

μ΄λ ‡κ²Œ 리슀트 두 개λ₯Ό λ§Œλ“€μ–΄μ£Όκ³  DP, 점화식을 μ„Έμ›Œμ£Όλ©΄ λœλ‹€. 

for i in range(1, 1000001):
    D[i] = D[i - 1] + in_time[i] - out_time[i - 1]

문제 μ‘°κ±΄μ—μ„œ "각 μ’Œμ„μ€ μ‚¬μš©μ΄ μ’…λ£Œλ˜λŠ” μ‹œκ°μ— κ³§λ°”λ‘œ 선택될 수 μ—†λ‹€."라고 ν–ˆμœΌλ‹ˆ 퇴μž₯μ‹œκ°„μ€ i - 1 μ‹œκ°μ„ λΉΌμ€€λ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄

D [n]은 n번째 μ‹œκ°μ— 선택할 수 μ—†λŠ” μ’Œμ„ 수(μ‚¬λžŒ 수라고 생각해도 될 λ“―)κ°€ λœλ‹€.

 

μ•„ 그리고 λ˜‘λ˜‘ν•œ 뢄듀은 μ•Œκ² μ§€λ§Œ μ €λ ‡κ²Œ 리슀트 두 개 μ‚¬μš© μ•ˆ 해도 λœλ‹€. out time값듀을  in_time에 -1둜 μ €μž₯ν•˜λ©΄ λœλ‹€. μ‹œκ°μ— 맞게.

λ‚˜λŠ” λ©”λͺ¨λ¦¬κ°€ λ„‰λ„‰ν•œ κ±° κ°™μ•„ λ‚΄ λ°©μ‹μœΌλ‘œ μž‘μ„±ν–ˆλ‹€.


전체 μ½”λ“œ

import sys
N = int(input())

in_time = [0] * 1000001
out_time = [0] * 1000001
D = [0] * 1000001

for _ in range(N):
    a, b = map(int, sys.stdin.readline().split())
    in_time[a] += 1
    out_time[b] += 1

for i in range(1, 1000001):
    D[i] = D[i - 1] + in_time[i] - out_time[i - 1]

Q = int(sys.stdin.readline().rstrip())
Qlist = [int(x) for x in sys.stdin.readline().split()]

for q in Qlist:
    print(D[q])

μ½”λ“œ μ„€λͺ…

for _ in range(N):
    a, b = map(int, sys.stdin.readline().split())
    in_time[a] += 1
    out_time[b] += 1

μ•žμ—μ„œ λ§ν•œ κ²ƒμ²˜λŸΌ μž…μž₯, 퇴μž₯ 각각 λ”°λ‘œ λ°›μ•„μ€€λ‹€.

 

for i in range(1, MAXTIME):
    D[i] = D[i - 1] + in_time[i] - out_time[i - 1]

그리고 점화식을 μ„Έμ›Œμ€€λ‹€. μ΄λ ‡κ²Œ (이미 μžˆλŠ” μ‚¬λžŒ + μž…μž₯ν•œ μ‚¬λžŒλ“€ - λ‚˜κ°„ μ‚¬λžŒλ“€) κ°„λ‹¨ν•˜κ²Œ κ΅¬ν˜„ κ°€λŠ₯ν•˜λ‹€.

 


μ§€κΈˆ 보면 κ°„λ‹¨ν•œ μ•„μ΄λ””μ–΄μ§€λ§Œ, ν…ŒμŠ€νŠΈ 같은 ν™˜κ²½μ—μ„œλŠ” κ΅¬ν˜„ν•˜κΈ° 쉽지 μ•Šλ‹€.

였히렀 기쑴에 λ‚΄κ°€ μ•Œκ³  μžˆλŠ” λ°©λ²•λ§Œ κ³ μ§‘ν•˜λŠ” κ±° κ°™λ‹€. 음... λ§Žμ€ μ—°μŠ΅, 체화 그리고 μ‹€μ „ κ²½ν—˜μ΄ 닡인 κ±° κ°™λ‹€.