Saya berjuang dengan masalah ini yang saya temukan di buku pemrograman kompetitif, tetapi tanpa solusi bagaimana melakukannya.
Untuk diberikan dua bilangan bulat A dan B (dapat ditampung dalam tipe bilangan bulat 64-bit), di mana A ganjil, temukan sepasang angka X dan Y sedemikian sehingga A = X * Y dan B = X xor Y. Pendekatan saya adalah mencantumkan semua pembagi dari A dan mencoba memasangkan angka di bawah sqrt (A) dengan angka lebih sqrt (A) yang multiply hingga A dan melihat apakah xor mereka adalah sama dengan B . Tetapi saya tidak tahu apakah itu cukup efisien. Apa solusi / algoritma yang baik untuk masalah ini?
algorithm
bit-manipulation
Aster W.
sumber
sumber
X*Y
atauX&Y
?Jawaban:
Berikut adalah rekursi sederhana yang mengamati aturan yang kita tahu: (1) bit paling tidak signifikan dari kedua X dan Y ditetapkan karena hanya multiplicand ganjil menghasilkan kelipatan ganjil; (2) jika kita menetapkan X untuk memiliki bit set B tertinggi, Y tidak boleh lebih besar dari sqrt (A); dan (3) mengatur bit dalam X atau Y sesuai dengan bit saat ini di B.
Kode Python berikut menghasilkan di bawah 300 iterasi untuk semua kecuali satu pasangan acak yang saya ambil dari kode contoh Matt Timmermans . Tapi yang pertama mengambil 231.199 iterasi :)
Keluaran:
sumber
Anda tahu bahwa setidaknya satu faktor adalah <= sqrt (A). Mari kita buat yang X.
Panjang X dalam bit akan menjadi sekitar setengah panjang A.
Bit atas X, oleh karena itu - yang nilainya lebih tinggi dari sqrt (A) - semuanya 0, dan bit yang sesuai dalam B harus memiliki nilai yang sama dengan bit yang sesuai di Y.
Mengetahui bit bagian atas Y memberi Anda kisaran yang cukup kecil untuk faktor yang sesuai X = A / Y. Hitung Xmin dan Xmax masing-masing sesuai dengan nilai terbesar dan terkecil yang mungkin untuk Y. Ingat bahwa Xmax juga harus <= sqrt (A).
Kemudian coba saja semua Xs yang mungkin antara Xmin dan Xmax. Tidak akan terlalu banyak, jadi tidak akan lama.
sumber
Cara mudah lainnya untuk menyelesaikan masalah ini bergantung pada kenyataan bahwa n bit XY dan X xor Y yang lebih rendah hanya bergantung pada n bit X dan Y yang lebih rendah. Oleh karena itu, Anda dapat menggunakan jawaban yang mungkin untuk n bit yang lebih rendah untuk membatasi jawaban yang mungkin untuk n + 1 bit yang lebih rendah , sampai Anda selesai.
Saya telah menemukan bahwa, sayangnya, mungkin ada lebih dari satu kemungkinan untuk satu n . Saya tidak tahu seberapa sering akan ada banyak kemungkinan, tetapi mungkin tidak terlalu sering sama sekali, jadi ini mungkin baik-baik saja dalam konteks kompetitif. Secara probabilitas, hanya akan ada beberapa kemungkinan, karena solusi untuk n bit akan memberikan 0 atau dua solusi untuk n + 1 bit, dengan probabilitas yang sama.
Tampaknya bekerja dengan cukup baik untuk input acak. Berikut kode yang saya gunakan untuk mengujinya:
Anda dapat melihat hasilnya di sini: https://ideone.com/cEuHkQ
Sepertinya biasanya hanya butuh beberapa ribu cek.
sumber