Je me bats avec ce problème que j'ai trouvé dans un livre de programmation compétitif, mais sans solution comment le faire.
Pour deux entiers donnés A et B (pouvant tenir dans un type entier 64 bits), où A est impair, trouvez une paire de nombres X et Y tels que A = X * Y et B = X xor Y. Mon approche était de lister tous les diviseurs de A et essayer d' appariement des nombres sous sqrt (A) avec des nombres plus sqrt (A) qui se multiplient à A et voir si leur xor est égal à B . Mais je ne sais pas si c'est assez efficace. Quelle serait une bonne solution / algorithme à ce problème?
algorithm
bit-manipulation
Aster W.
la source
la source
X*Y
ouX&Y
?Réponses:
Voici une récursivité simple qui observe les règles que nous connaissons: (1) les bits les moins significatifs de X et Y sont définis car seuls les multiplicandes impairs donnent un multiple impair; (2) si nous réglons X pour avoir le bit de B le plus élevé, Y ne peut pas être supérieur à sqrt (A); et (3) définir des bits dans X ou Y en fonction du bit actuel dans B.
Le code Python suivant a entraîné moins de 300 itérations pour toutes les paires aléatoires, sauf une, que j'ai choisies dans l' exemple de code de Matt Timmermans . Mais le premier a pris 231 199 itérations :)
Production:
la source
Vous savez qu'au moins un facteur est <= sqrt (A). Faisons celui-là X.
La longueur de X en bits sera environ la moitié de la longueur de A.
Les bits supérieurs de X, donc - ceux dont la valeur est supérieure à sqrt (A) - sont tous à 0, et les bits correspondants dans B doivent avoir la même valeur que les bits correspondants dans Y.
Connaître les bits supérieurs de Y vous donne une assez petite plage pour le facteur correspondant X = A / Y. Calculez Xmin et Xmax correspondant aux valeurs les plus grandes et les plus petites possibles pour Y, respectivement. N'oubliez pas que Xmax doit également être <= sqrt (A).
Essayez ensuite tous les X possibles entre Xmin et Xmax. Il n'y en aura pas trop, donc ça ne prendra pas très longtemps.
la source
L'autre façon simple de résoudre ce problème repose sur le fait que les n bits inférieurs de XY et X xor Y dépendent uniquement des n bits inférieurs de X et Y. Par conséquent, vous pouvez utiliser les réponses possibles pour les n bits inférieurs pour restreindre les réponses possibles pour les n + 1 bits inférieurs , jusqu'à ce que vous ayez terminé.
J'ai compris que, malheureusement, il peut y avoir plus d'une possibilité pour un seul n . Je ne sais pas combien de fois il y aura beaucoup de possibilités, mais ce n'est probablement pas trop souvent, donc cela peut être bien dans un contexte concurrentiel. Probablement, il n'y aura que quelques possibilités, car une solution pour n bits fournira soit 0, soit deux solutions pour n + 1 bits, avec une probabilité égale.
Il semble fonctionner assez bien pour une entrée aléatoire. Voici le code que j'ai utilisé pour le tester:
Vous pouvez voir les résultats ici: https://ideone.com/cEuHkQ
On dirait que cela ne prend généralement que quelques milliers de chèques.
la source