https://www.acmicpc.net/problem/1561
이분 탐색 문제였습니다.
📕 풀이방법
📔 입력 및 초기화
탑승자 아이들의 수 child, 놀이기구 수 attractions, 각 놀이기구별 탐승시간 ride_times선언 후 입력 받습니다.
📔 풀이과정
무엇에 대해 이분탐색을 해야하는지 찾기가 쉽지 않았습니다. 처음 탑승할 아이의 수가 많기 때문에 그 숫자에 힌트를 얻어 아이에 대해 이분탐색을 진행했으나 각 놀이기구마다 탐승 가능한 아이의 수가 제각각 다르기 때문에 반대로 특정 시간(last_time)이 지났을 때 누적된 탑승자 수가 입력 받은 child값과 일치하는지 확인하는 방식으로 접근해야합니다.
1. 이분 탐색을 진행해줍니다.
1-1. left와 right변수를 설정해 시간을 이분 탐색합니다. left는 0으로 right는 충분히 큰 값(20억 * 30)으로 초기화힙니다.
1-2. 해당 범위는 각 놀이기구가 한 아이를 태우는 데 걸리는 최대 시간만큼 잡았습니다.
1-3. 이분 탐색 중간 지점 mid를 선언 후 구해주고 각 놀이기구가 mid시간 동안 몇 명의 아이를 태울 수 있는지 계산합니다. ride_times를 O(M)으로 순회하면 구할 수 있습니다. loop를 수행하며 mid // 각 놀이기구의 시간 값을 더해 지역변수 passenger에 더해줍니다.
1-4. passenger >= child라면 탑승자가 줄어도 되므로 시간을 줄여줍니다. right = mid - 1로 갱신하며 last_time값을 mid로 저장합니다. child값과 같을 때 last_time이 정확히 mid여야 하기 때문입니다. 반대로 passenger가 child보다 작으면 left를 늘려 더 많은 탑승자가 탈 수 있도록 해줍니다.
2. last_time에서 정확한 탑승 위치를 찾습니다.
2-1. 이분 탐색 이후에 last_time에 해당하는 시간 직전에서의 누적 탑승자 수를 계산합니다. 2-2.last_time에서 각 놀이기구가 나머지 없이 탑승 가능한지 확인해 child번째 아이가 탑승하는 놀이기구의 번호를 찾습니다. 이는 각 놀이기구의 탑승 시간 ride_times에 대해 for loop를 수행하며 last_time을 각 시간으로 나눠떨어지면 passenger를 추가시키고 이 때 값이 child와 일치하면 해당 놀이기구 번호를 반환하면 됩니다.
📔 정답 출력 | 반환
last_time기점으로 마지막 탑승자가 탔을 때 놀이기구 번호를 반환합니다.
📕 Code
📔 Python3
import sys
input = sys.stdin.readline
def find_time(child, attractions, ride_times):
if child <= attractions:
return child
left, right = 0, 2000000000 * 30
last_time = 0
while left <= right:
mid = (left + right) // 2
passenger = attractions
for time in ride_times:
passenger += mid // time
if passenger >= child:
last_time = mid
right = mid - 1
else:
left = mid + 1
passenger = attractions
for time in ride_times:
passenger += (last_time - 1) // time
for i, time in enumerate(ride_times):
if last_time % time == 0:
passenger += 1
if passenger == child:
return i + 1
return -1
child, attractions = map(int, input().split())
ride_times = list(map(int, input().split()))
print(find_time(child, attractions, ride_times))
*더 나은 내용을 위한 지적, 조언은 언제나 환영합니다.
'Algorithm > Binary Search' 카테고리의 다른 글
(Python3) - LeetCode (Medium) : 2054. Two Best Non-Overlapping Events (1) | 2024.12.08 |
---|---|
(Python3) - LeetCode (Medium) : 1760. Minimum Limit of Balls in a Bag (1) | 2024.12.07 |
(C++, Rust) - LeetCode (easy) 222. Count Complete Tree Nodes (0) | 2023.08.17 |
(C++) - LeetCode (easy) 744. Find Smallest Letter Greater Than Target (0) | 2023.06.28 |
(C++) - LeetCode (easy) 704. Binary Search (0) | 2023.06.19 |