Saya memiliki bilangan bulat N. Saya harus menemukan bilangan bulat terkecil yang lebih besar dari N yang tidak mengandung angka selain 0 atau 1. Misalnya: Jika N = 12
jawabannya adalah 100
. Saya telah mengkodekan pendekatan brute force di C ++.
int main() {
long long n;
cin >> n;
for (long long i = n + 1; ; i++) {
long long temp = i;
bool ok = true;
while (temp != 0) {
if ( (temp % 10) != 0 && (temp % 10) != 1) {
ok = false;
break;
}
temp /= 10;
}
if (ok == true) {
cout << i << endl;
break;
}
}
}
Masalahnya adalah, pendekatan saya terlalu lambat. Saya percaya ada pendekatan yang sangat efisien untuk menyelesaikan ini. Bagaimana saya bisa menyelesaikan masalah ini secara efisien?
N
diperbolehkan? Juga, ini sulit karena Anda berisiko meluap tipe Anda. Apa batasannyaN
?Jawaban:
Kenaikan N,
Mulai dari kiri, pindai hingga Anda menemukan angka di atas 1. Tambahkan nomor parsial sebelum dan nolkan sisanya.
Misalnya
Bukti:
Nomor yang diminta harus minimal N +1, ini sebabnya kami menambah. Kami sekarang mencari angka yang lebih besar atau sama.
Mari kita panggil awalan angka 0/1 awal dan akhiran apa yang terjadi setelahnya. Kita harus mengganti digit pertama akhiran dengan nol dan menetapkan awalan yang lebih besar. Awalan terkecil yang cocok adalah awalan saat ini ditambah satu. Dan sufiks terkecil yang cocok adalah semua nol.
Memperbarui:
Saya lupa menentukan bahwa awalan harus ditambah sebagai angka biner , jika tidak, angka terlarang dapat muncul.
sumber
Kemungkinan lain adalah yang berikut:
Anda mulai dengan angka desimal terbesar dari tipe "1111111 ... 1111" yang didukung oleh tipe data yang digunakan
Algoritme mengasumsikan bahwa input lebih kecil dari angka ini; jika tidak, Anda harus menggunakan tipe data lain.
Contoh: Saat menggunakan
long long
, Anda mulai dengan nomornya1111111111111111111
.Contoh
Bukti kebenaran:
Kami memproses digit demi digit dalam algoritma ini. Di setiap langkah, ada digit yang nilainya sudah diketahui dan digit yang nilainya belum diketahui.
Di setiap langkah, kami menyelidiki digit paling tidak dikenal yang paling kiri.
Kami menetapkan digit itu ke "0" dan semua digit tidak dikenal lainnya menjadi "1". Karena digit yang akan diselidiki adalah yang paling signifikan dari digit yang tidak diketahui, angka yang dihasilkan adalah angka terbesar yang mungkin dengan digit itu menjadi "0". Jika angka ini kurang atau sama dengan input, digit yang diperiksa harus berupa "1".
Di sisi lain, angka yang dihasilkan lebih kecil dari semua angka yang mungkin di mana angka yang diselidiki adalah "1". Jika angka yang dihasilkan lebih besar dari input, digit harus "0".
Ini berarti bahwa kita dapat menghitung satu digit di setiap langkah.
Kode C
(Kode C juga harus bekerja di bawah C ++):
sumber
Izinkan saya menyarankan beberapa alternatif.
I. Bertambah. Anggap itu modifikasi metode @YvesDaoust.
(a) jika kurang dari 2 maka biarkan semuanya apa adanya
(b) jika tidak, setel ke 0 dan tambah sebelumnya
Contoh:
Anda mendapatkan hasil dalam format desimal.
II Pemisah.
(a) jika M melebihi 1 maka tambah D
(b) jika tidak, tambah jumlah dengan M * 10 k , di mana k adalah angka iterasi saat ini (dimulai dengan 0)
Contoh 1:
Contoh 2:
Contoh 3:
Contoh 4:
sumber