Олимпиадная задача "Незуко на поляне"
У меня возникли трудности при решении задачи "Незуко на поляне" с Codeforces.
Я уверен в том, что движусь в нужном направлении. Но логика с указателями у меня хромает. Бьюсь с этой задачей полтора часа и уже уперся в потолок, так сказать. Направьте меня на верное решение.
Условие задачи
Незуко внезапно очнулась на числовой прямой в точке 0 и имеет h единиц здоровья. Она хочет добраться до точки d. За один ход она может сделать ровно одно из двух:
- отдохнуть в тени и повысить текущее здоровье на 1;
- переместиться из текущей точки x в x+1.
Каждое перемещение снижает здоровье Незуко; если перемещение является j-м перемещением подряд, то её здоровье снизится на j единиц. Если в результате хода здоровье Незуко опустится до 0 или ниже, то она не может сделать такой ход.
Например, если у Незуко изначально было 7 единиц здоровья и d=4, её ходы могли выглядеть следующим образом:
Переместиться из 0 в 1 и снизить здоровье на 1. Теперь она находится в точке 1 с 6 единицами здоровья.
Переместиться из 1 в 2 и снизить здоровье на 2. Теперь она находится в точке 2 с 4 единицами здоровья.
Переместиться из 2 в 3 и снизить здоровье на 3. Теперь она находится в точке 3 с 1 единицей здоровья.
Отдохнуть и восстановить 1 единицу здоровья. Теперь она находится в точке 3 с 2 единицами здоровья.
Переместиться из 3 в 4 и снизить здоровье на 1. Теперь она находится в точке 4 с 1 единицей здоровья.
Найдите минимальное количество ходов, необходимое, чтобы добраться до точки d.
Входные данные
Каждый тест состоит из нескольких наборов входных данных.
В первой строке находится одно целое число t (1≤t≤104) — количество наборов входных данных. Далее следует описание наборов входных данных.
Первая строка каждого набора входных данных содержит два числа h и d (1≤h,d≤109) — количество единиц здоровья и конечная точка, соответственно.
Выходные данные
Для каждого набора входных данных выведите одно число — минимальное число ходов, необходимых Незуко, чтобы добраться до точки d.
Пример
# Входные данные
5
3 2
1 1
5 3
2 4
10 7
# Выходные данные
3
2
4
7
10
Примечание
В первом наборе входных данных h=3, d=2 действия могут быть такими:
Переместиться из 0 в 1 и снизить здоровье на 1. Теперь она находится в точке 1 с 2 единицами здоровья.
Отдохнуть и восстановить 1 единицу здоровья. Теперь она находится в точке 1 с 3 единицами здоровья.
Переместиться из 1 в 2 и снизить здоровье на 1. Теперь она находится в точке 2 с 2 единицами здоровья.
Итого, 3 хода.
В четвёртом наборе входных данных h=2, d=4 действия могут быть такими:
Переместиться из 0 в 1 и снизить здоровье на 1. Теперь она находится в точке 1 с 1 единицей здоровья.
Отдохнуть и восстановить 1 единицу здоровья. Теперь она находится в точке 1 с 2 единицами здоровья.
Переместиться из 1 в 2 и снизить здоровье на 1. Теперь она находится в точке 2 с 1 единицей здоровья.
Отдохнуть и восстановить 1 единицу здоровья. Теперь она находится в точке 2 с 2 единицами здоровья.
Переместиться из 2 в 3 и снизить здоровье на 1. Теперь она находится в точке 3 с 1 единицей здоровья.
Отдохнуть и восстановить 1 единицу здоровья. Теперь она находится в точке 3 с 2 единицами здоровья.
Переместиться из 3 в 4 и снизить здоровье на 1. Теперь она находится в точке 4 с 1 единицей здоровья.
Итого, 7 ходов.
Мое решение
t = int(input())
for _ in range(t):
h, d = map(int, input().split())
left, right = 0, d
moves = rest = 0 # счётчик отдыхов и пройденных клеток
health = h
while left <= right:
# кол-во шагов на mid клеток вперед
mid = left + (right - left) // 2
# если после шага health <= 0, то отдыхаем
if mid * (moves + (moves + mid)) // 2 >= health:
rest += 1
health += 1
right = mid - 1
# иначе - идем
else:
moves += mid
health -= mid * (moves + (moves + mid)) // 2
left = mid + 1
# мин. кол-во шагов до финиша = отдых + кол-во пройденных клеток
print(rest + moves)