Estou enfrentando esse problema que encontrei em um livro de programação competitivo, mas sem uma solução sobre como fazê-lo.
Para dois números inteiros A e B (pode caber no tipo inteiro de 64 bits), onde A é ímpar, encontre um par de números X e Y de modo que A = X * Y e B = X x ou Y. Minha abordagem foi listar todos os divisores de um e tente emparelhar números sob sqrt (a) com números sobre sqrt (a) que se multiplicam até um e ver se sua xor é igual a B . Mas não sei se isso é eficiente o suficiente. Qual seria uma boa solução / algoritmo para esse problema?
algorithm
bit-manipulation
Aster W.
fonte
fonte
X*Y
ouX&Y
?Respostas:
Aqui está uma recursão simples que observa as regras que conhecemos: (1) os bits menos significativos de X e Y são definidos, pois apenas multiplicandos ímpares produzem um múltiplo ímpar; (2) se definirmos X para ter o bit mais alto de B, Y não poderá ser maior que sqrt (A); e (3) definir bits em X ou Y de acordo com o bit atual em B.
O código Python a seguir resultou em menos de 300 iterações para todos, exceto um dos pares aleatórios que escolhi do código de exemplo de Matt Timmermans . Mas o primeiro fez 231.199 iterações :)
Resultado:
fonte
Você sabe que pelo menos um fator é <= sqrt (A). Vamos fazer aquele X.
O comprimento de X em bits será cerca de metade do comprimento de A.
Os bits superiores de X, portanto - aqueles com valor superior a sqrt (A) - são todos 0 e os bits correspondentes em B devem ter o mesmo valor que os bits correspondentes em Y.
Conhecer os bits superiores de Y fornece um intervalo bastante pequeno para o fator correspondente X = A / Y. Calcule Xmin e Xmax correspondentes aos maiores e menores valores possíveis para Y, respectivamente. Lembre-se de que Xmax também deve ser <= sqrt (A).
Depois, tente todos os Xs possíveis entre Xmin e Xmax. Não haverá muitos, por isso não vai demorar muito.
fonte
A outra maneira direta de resolver esse problema é o fato de que os n bits inferiores de XY e X xor Y dependem apenas dos n bits inferiores de X e Y. Portanto, você pode usar as respostas possíveis para restringir os n bits inferiores as respostas possíveis para os n + 1 bits mais baixos , até você terminar.
Descobri que, infelizmente, pode haver mais de uma possibilidade para um único n . Não sei com que frequência haverá muitas possibilidades, mas provavelmente não é com muita frequência, se é que isso pode ser bom em um contexto competitivo. Probabilisticamente, haverá apenas algumas possibilidades, uma vez que uma solução para n bits fornecerá 0 ou duas soluções para n + 1 bits, com igual probabilidade.
Parece funcionar muito bem para entrada aleatória. Aqui está o código que eu usei para testá-lo:
Você pode ver os resultados aqui: https://ideone.com/cEuHkQ
Parece que normalmente leva apenas alguns milhares de cheques.
fonte