728x90
시간 제한 2초, 메모리 제한 1024MB
# 조건
- 이진 트리 모양의 땅으로 이루어진 꽉꽉마을에는 오리들이 살고 있다. 땅 번호는 다음과 같이 매겨진다.
- 루트 땅의 번호는 1이다.
- 어떤 땅의 번호가 K라면, 왼쪽 자식 땅의 번호는 2 × K, 오른쪽 자식 땅의 번호는 2 × K + 1이다.
- 어느날 오리들끼리 부동산 다툼이 일어나서 꽉꽉마을 촌장 경완이가 해결책을 가져왔고, 그 내용은 다음과 같다.
- 오리들을 한 줄로 대기시킨다. 맨 처음 오리들은 1번 땅에 위치해 있다.
- 오리들이 서있는 순서대로 원하는 땅을 가지도록 한다.
- 만약, 한 오리가 원하는 땅까지 가는 길에 이미 다른 오리가 점유한 땅이 있다면 막대한 세금을 내야 하는 이유로 해당 땅을 지나가지 못해 그 오리는 땅을 가지지 못한다.
- 오리가 원하는 땅까지 가는 길에는 오리가 원하는 땅도 포함된다.
- 경완이의 해결책대로 땅 분배를 했을 때 각 오리별로 원하는 땅을 가질 수 있는지, 가질 수 없다면 처음 마주치는 점유된 땅의 번호를 구해보자.
입력
- 첫 번째 줄에 땅 개수 N과 꽉꽉나라에 사는 오리 수 Q가 공백으로 구분되어 주어진다. (2 ≤ N < 220, 1 ≤ Q ≤ 200,000)
- 두 번째 줄부터 차례로 Q개의 줄에 걸쳐 i+1번째 줄에는 i번째 오리가 원하는 땅 번호 xi_가 주어진다. (2 ≤ _xi ≤ N)
출력
- Q개의 줄에 원하는 땅에 갈 수 있다면 0을, 갈 수 없다면 처음 마주치는 점유된 땅의 번호를 출력한다.
# 접근 방법
- 전형적인 트리 문제이다.
- 우선 점유된 땅을 표시할 tree 리스트를 N+1개의 크기만큼 만들어준다.
- 이후 오리들이 원하는 땅을 입력받고 check 함수를 수행해준다.
- 인자로는 현재 탐색할 땅 번호와 기존에 점유된 땅을 지났는지의 여부이다.
- 현재 땅 (idx) = 1이라면 루트 땅까지 왔으므로 flag를 리턴해준다.
- 그렇지 않다면 3가지 조건으로 나눈다.
- 현재 점유된 땅을 지나지 않았고 지금 땅도 비어있는 경우
- 현재 땅이 점유되어 있는 경우
- 점유된 땅을 지나서 온 경우
- 현재 땅이 점유되어 있는 경우를 우선적으로 조건문을 넣어준 이유는 가장 깊은 곳에서 출발하기 때문에 맨 처음 만나는 땅으로 flag를 변경시켜주기 위해서이다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
def check(idx, flag):
if idx == 1:
return flag
if not flag and not tree[idx]:
result = check(idx//2, flag)
elif tree[idx]:
result = check(idx//2, idx)
elif flag:
result = check(idx//2, flag)
return result
N, Q = map(int, input().split())
tree = [False] * (N+1)
for _ in range(Q):
num = int(input())
val = check(num, 0)
if not val:
print(0)
tree[num] = True
else:
print(val)
728x90
'ALGORITHM > 자료구조' 카테고리의 다른 글
[백준 20924번] 파이썬 - 트리의 기둥과 가지 (1) | 2023.10.24 |
---|---|
[백준 5052번] 파이썬 - 전화번호 목록 (1) | 2023.10.20 |
[백준 4358번] 파이썬 - 생태학 (0) | 2023.10.05 |
[백준 1158번] 파이썬 - 요세푸스 문제 (0) | 2023.09.23 |
[백준 17298번] 파이썬 - 오큰수 (2) | 2023.09.15 |