Преобразование числа m в n с минимальными операциями. Разрешенные операции были вычитанием на 1 и умножением на 2.BFS для арифметических операций
Для примера: 4 и 6. Ответ равен 2. 1-я операция: -1 -> 4-1 = 3. Вторая операция: * -> 3 * 2 = 6.
Я использую подход BFS для конкретного ввода (src = 26, dst = 5), он занимает много времени. Я делаю что-то неправильно?
from queue_class import queue
class node:
def __init__(self, value, level, parent):
self.level = level
self.value = value
self.parent = parent
def get_minimum_distance(src, target, q):
if src == target:
return 0
seen_list = []
data = node(src, 0, -1)
q.enqueue(data)
while not q.isempty():
data = q.dequeue()
if data == "sentinel":
break
if data.value == target:
# let's print what has got me here
while data.parent != -1:
print(data.value)
data = data.parent
return "finally reached"
if data.value in seen_list:
continue
seen_list.append(data.value)
# two operations are allowed i.e. -1 and multiplication by 2
# check if two numbers have opposite sign and if they have
# then check if the current number being subtracted from is a negative
# number. If it is, then there is no point subtracting 1 from that
if ((data.value^target) < 0 and data.value > 0) or (data.value^target >= 0):
q.enqueue(node(data.value - 1, data.level + 1, data))
q.enqueue(node(data.value * 2, data.level + 1, data))
return -1
q = queue(1 << 20)
print(get_minimum_distance(26, 5, q))
Выполнение очереди выполняется here.
Благодаря Paul: Ниже приведен код, который я привел с приведенным ниже кодом в python, и он отлично работает.
def get_minimum_operations(src, dst):
step = 0
operations = []
if src == dst:
return 0
if dst < src:
return src-dst
while dst > src:
if dst & 0x01:
step += 1
operations.append("-1")
dst = (dst+1) >> 1
operations.append("*2")
step += 1
for i in range(0, src-dst):
operations.append("-1")
return (((src - dst) + step), operations)
src = 38
dst = 100
output = ""
(steps, operations) = get_minimum_operations(src, dst)
print(steps)
try:
while operations:
i = operations.pop()
if i == "*2":
if output == "":
output += "(" + str(src) + "*2" + ")"
else:
output = "(" + output + "*2" + ")"
if i == "-1":
if output == "":
output += "(" + str(src) + "-1" + ")"
else:
output = "(" + output + "-1" + ")"
except IndexError:
pass
print(output)
Извините, но ваш ответ непонятен. Можете ли вы уточнить: «Подключения можно легко минимизировать из-за следующего факта: (a - 1) * 2 = a * 2 - 2"? Было бы неплохо привести несколько примеров, и ваше решение не будет работать. Http://ideone.com/OQNsY2 –
@nomanpouigt. О минимизации количества подстрок просто зависит от того, что вы можете написать '(a - 1) * Вместо 'a * 2 - 1 - 1', что уменьшает количество операций на единицу. То же самое относится и к более высоким номерам. Что касается вашего кода, в строке 8 есть ошибка ('int s = a << (n - b);' должно быть 'int s = (a << n) - b;'). Sry, я забыл положить эти скобки в код, я исправлю это. Просто замените эту строку, и она работает. – Paul
понял, но как этот факт помогает в сокращении числа операций при преобразовании из a в b? Это помогает только тогда, когда мы хотим преобразовать из a в b, который должен быть равен (a-1) * 2 (это не сила 2, а просто четное число). Однако в случае b не равно (a-1) * 2 то что? –