По заданным целым числам A и B найдите целое число X так, чтобы:
- A, B <2 * 1e18
- A xor X = B + X
Я очень сомневаюсь, что это уравнение можно решить с помощью математики. Это проблема кодирования, с которой я столкнулся 3 года назад, и даже сейчас я не могу решить ее самостоятельно.
Мой код до сих пор: (это решение грубой силы)
#include <iostream>
using namespace std;
int main()
{
unsigned long long a, b;
cin >> a >> b;
for (unsigned long long x = 1; x < max(a, b); x++) {
unsigned long long c = a ^ x;
unsigned long long d = b + x;
if (c == d) {
cout << x << endl;
break;
return 0;
}
}
cout << -1; //if no such integer exists
return 0;
}
a xor b = a + b mod 2
. Попробуйте немного подумать об этой эквивалентности.mod 2
как в математическом (мод 2), то есть 3 === 7 (мод 2). Дело в том, что вы можете найти уравнение для первого бита X, а затем перейти к следующему биту, где (с учетом переноса) вы получите уравнение для второго бита и т. Д., Как в ответе Даниэля.Ответы:
Обратите внимание, что
A + X == (A xor X) + ((A and X)<<1)
. Так:И у нас есть:
Если условие выполняется, для любого целого числа Y, у которого нет битов, установленных в A, (((A - B) >> 1) или Y) является решением. Если вам нужно только одно решение, вы можете использовать ((A - B) >> 1), где Y = 0. В противном случае решения не существует.
источник
A xor X
это «добавление без переноса» и((A and X)<<1)
«перенос в добавлении». ПосколькуA + X
это «сложение с переносом», первое уравнение имеет смысл.(A and X)<<1
в основном2*(A and X)
и потому, что это равноA-B
ему, говорит, что проблема может иметь решение, только если A и B оба нечетные или оба события.Это не очень сложно, нужно просто думать мало: предположим , что мы пишем
A
,B
иX
в двоичном коде иAᵢ
это значение , соответствующее крайнее правое 2 ⁱ бит.Мы знаем , что:
Aₒ ⊕ Xₒ = Bₒ + Xₒ
.Давайте рассмотрим пример, чтобы узнать, как это оценить: A = 15 и B = 6. Преобразование в двоичный файл:
Теперь у нас есть некоторые возможности. Давайте проанализируем самые правые биты A и B:
Мы знаем, что
d
может быть только 0 или 1, поэтому:Заметно, что XOR ведет себя подобно двоичной сумме (с той разницей, что XOR не создает перенос для следующей битовой суммы):
так что не всегда будет возможно найти X, который удовлетворяет
A ⊕ X = B + X
, потому что нет значения,d
которое удовлетворяет1 + d = 0 + d
.В любом случае, если X существует, вы можете просто найти его таким образом, справа налево, находя постепенно.
РАБОЧИЙ ПОЛНЫЙ ПРИМЕР
А = 15, В = 7:
Здесь применимы как d = 0, так и d = 1, тогда что? Нам нужно проверить следующий бит. Предположим, что d = 1:
поэтому в этом случае d должно быть 0.
а как насчет б? нам нужно проверить следующий бит, как всегда:
а теперь для
a
:здесь
a
могут быть 0 и 1, но это должно быть 0, чтобы избежать переноса в суммуB + X
.Тогда,
X = 0 1 0 0
таким образом, X = 4.КОД
Вы можете проверить это здесь .
источник