Я борюсь с этой проблемой, которую нашел в конкурентной книге по программированию, но без решения, как это сделать.
Для заданных двух целых чисел A и B (может соответствовать 64-разрядному целочисленному типу), где A нечетно, найдите пару чисел X и Y, такую, что A = X * Y и B = X или Y. Мой подход заключался в том, чтобы перечислить все делители а и попробуйте спаривания номера под SQRT (а) с номерами над SQRT (A) , которые размножаются до а и посмотреть , если их исключающее равно B . Но я не знаю, достаточно ли это эффективно. Каково было бы хорошее решение / алгоритм для этой проблемы?
algorithm
bit-manipulation
Астер В.
источник
источник
X*Y
илиX&Y
?Ответы:
Вот простая рекурсия, которая соблюдает известные нам правила: (1) устанавливаются младшие значащие биты как X, так и Y, поскольку только нечетные мультипликаторы дают нечетное кратное число; (2) если мы установим для X самый высокий установленный бит B, Y не может быть больше sqrt (A); и (3) установить биты в X или Y в соответствии с текущим битом в B.
Следующий код Python дал менее 300 итераций для всех, кроме одной случайной пары, которую я выбрал из примера кода Мэтта Тиммерманса . Но первый занял 231 199 итераций :)
Вывод:
источник
Вы знаете, что по крайней мере один фактор <= sqrt (A). Давайте сделаем это один X.
Длина X в битах будет примерно вдвое меньше длины A.
Следовательно, все старшие биты X - те, которые имеют более высокое значение, чем sqrt (A), - равны 0, и соответствующие биты в B должны иметь то же значение, что и соответствующие биты в Y.
Знание старших битов Y дает вам довольно маленький диапазон для соответствующего коэффициента X = A / Y. Вычислите Xmin и Xmax, соответствующие наибольшим и наименьшим возможным значениям для Y соответственно. Помните, что Xmax также должен быть <= sqrt (A).
Затем просто попробуйте все возможные X между Xmin и Xmax. Там не будет слишком много, поэтому это не займет много времени.
источник
Другой простой способ решения этой проблемы заключается в том, что младшие n битов XY и X xor Y зависят только от младших n битов X и Y. Поэтому вы можете использовать возможные ответы для младших n битов, чтобы ограничить возможные ответы для младших n + 1 бит, пока вы не закончите.
Я понял, что, к сожалению, может быть более одной возможности для одного n . Я не знаю, как часто будет много возможностей, но это, вероятно, не так уж часто, если вообще так, так что это может быть хорошо в конкурентном контексте. Вероятно, будет только несколько возможностей, поскольку решение для n битов обеспечит либо 0, либо два решения для n + 1 битов с равной вероятностью.
Кажется, это работает довольно хорошо для случайного ввода. Вот код, который я использовал для его проверки:
Вы можете увидеть результаты здесь: https://ideone.com/cEuHkQ
Похоже, что обычно требуется всего несколько тысяч проверок.
источник