0. 문제 링크
https://www.acmicpc.net/problem/12757
12757번: 전설의 JBNU
첫 줄에는 초기 데이터의 개수인 \(N(1 \le N \le 100,000)\) 과 명령 횟수인 \(M(1 \le M \le 100,000)\), 가장 근접한 Key까지의 거리의 제한인 \(K(1 \le K \le 10,000)\)가 주어진다. 입력의 둘째 줄부터 N개의 줄에
www.acmicpc.net
1. 풀이 방법
눈 씻고 봐도 쌩구현 문제
(+정정, 구현 아니고 탐색 관련 문제였음)
가장 중요한건 인접한 키를 찾는 로직이 가장 중요하다.
이때 Linear로 인접한 키를 구하는 순간 시간 초과가 난다.
따라서 다른 방법으로 탐색해야 한다.
나는 이진 탐색을 골랐다.
아마 더 좋은 방법이 있을 거라 생각한다.
2. 코드
import sys
import bisect
input = sys.stdin.readline
def find_adj(key):
idx = bisect.bisect_left(key_list, key)
if idx == 0:
# 첫 번째로 들어갈 때
if abs(key_list[0] - key) <= k:
return key_list[0]
elif idx == len(key_list):
# 마지막으로 들어갈 때
if abs(key_list[-1] - key) <= k:
return key_list[-1]
else:
# 만약 사이에 낑길 경우
l_idx, r_idx = key - key_list[idx - 1], key_list[idx] - key
if l_idx == r_idx and l_idx <= k:
return -1
elif l_idx < r_idx and l_idx <= k:
return key_list[idx - 1]
elif l_idx > r_idx and r_idx <= k:
return key_list[idx]
return -2
if __name__ == "__main__":
n, m, k = map(int, input().split())
db = dict()
key_list = list()
for _ in range(n):
key, value = map(int, input().split())
if key not in db:
db[key] = value
bisect.insort(key_list, key)
for _ in range(m):
opt = list(map(int, input().split()))
match opt[0]:
case 1:
db[opt[1]] = opt[2]
bisect.insort(key_list, opt[1])
case 2:
if opt[1] in db:
db[opt[1]] = opt[2]
else:
index = find_adj(opt[1])
if index != -1 and index != -2:
db[index] = opt[2]
case 3:
if opt[1] in db:
print(db[opt[1]])
else:
index = find_adj(opt[1])
if index == -1:
print('?')
elif index == -2:
print(-1)
else:
print(db[index])
3. 마무리
'Computer Science > 알고리즘' 카테고리의 다른 글
[백준 - Python] 22866 - 탑 보기 (0) | 2023.04.12 |
---|---|
[백준 - Python] 14950 - 정복자 (1) | 2023.04.12 |
[백준 - Python] 6068 - 시간 관리하기 (0) | 2023.04.04 |
[백준 - Python] 12764 - 싸지방에 간 준하 (0) | 2023.04.04 |
[백준 - Python] 20440 - 🎵니가 싫어 싫어 너무 싫어 싫어 오지 마 내게 찝쩍대지마🎵 - 1 (0) | 2023.03.27 |