Dato un numero intero N. Qual è il numero intero più piccolo maggiore di N che ha solo 0 o 1 come cifre?


15

Ho un numero intero N. Devo trovare il numero intero più piccolo maggiore di N che non contenga alcuna cifra diversa da 0 o 1. Ad esempio: Se N = 12la risposta è allora 100. Ho codificato un approccio di forza bruta in 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;
        }
    }
}

Il problema è che il mio approccio è troppo lento. Credo che ci sia un approccio molto efficace per risolvere questo problema. Come posso risolvere questo problema in modo efficiente?


4
Inizia con le unità. Se la cifra è diversa da 0 o 1 metti uno zero e porta 1. Ripeti per ogni posizione
Sembei Norimaki

1
Questo descrive un problema simile. Aiuta forse
TomBombadil,

Il negativo è Npermesso? Inoltre, questo è difficile poiché rischi di traboccare il tuo tipo. Quali sono i limiti N?
Bathsheba,

1
@SembeiNorimaki: questo è sbagliato. Resterà invariato un numero composto esclusivamente da 0 e 1. E ci sono altri errori.
Yves Daoust,

1
@SembeiNorimaki: ho detto che ci sono altri fallimenti. Rimangono, poiché il tuo metodo è sbagliato. Prova i numeri interi da 1 a 50 e troverai errori. Errare humanum, perseverare diabolicum.
Yves Daoust,

Risposte:


20
  1. Incremento N,

  2. A partire da sinistra, scansiona fino a trovare una cifra sopra 1. Aumenta il numero parziale prima di esso e azzera il resto.

Per esempio

12 -> 13 -> 1|3 -> 10|0
101 -> 102 -> 10|2 -> 11|0
109 -> 110 -> 110|
111 -> 112 -> 11|2 -> 100|0
198 -> 199 -> 1|99 -> 10|00
1098 -> 1099 -> 10|99 -> 11|00
10203 -> 10204 -> 10|204 -> 11|000
111234 -> 111235 -> 111|235 -> 1000|000
...

Prova:

Il numero richiesto deve essere almeno N + 1, per questo motivo incrementiamo. Ora stiamo cercando un numero maggiore o uguale.

Chiamiamo il prefisso le cifre iniziali 0/1 e il suffisso che segue. Dobbiamo sostituire la prima cifra del suffisso con uno zero e impostare un prefisso più grande. Il prefisso più piccolo che si adatta è il prefisso corrente più uno. E il suffisso più piccolo che si adatta è tutti gli zero.


Aggiornare:

Ho dimenticato di specificare che il prefisso deve essere incrementato come un numero binario , altrimenti potrebbero apparire cifre vietate.


7

Un'altra possibilità sarebbe la seguente:

  • Si inizia con il numero decimale più grande del tipo "1111111 ... 1111" supportato dal tipo di dati utilizzato

    L'algoritmo presuppone che l'input sia inferiore a questo numero; altrimenti dovrai usare un altro tipo di dati.

    Esempio: quando si utilizza long long, si inizia con il numero 1111111111111111111.

  • Quindi elaborare ogni cifra decimale da sinistra a destra:
    • Prova a cambiare la cifra da 1 a 0.
    • Se il risultato è ancora maggiore del tuo input, fai la modifica (cambia la cifra in 0).
    • Altrimenti la cifra rimane 1.

Esempio

Input = 10103
Start:  111111
Step 1: [1]11111, try [0]11111; 011111 > 10103 => 011111 
Step 2: 0[1]1111, try 0[0]1111; 001111 < 10103 => 011111
Step 3: 01[1]111, try 01[0]111; 010111 > 10103 => 010111
Step 4: 010[1]11, try 010[0]11; 010011 < 10103 => 010111
Step 5: 0101[1]1, try 0101[0]1; 010101 < 10103 => 010111
Step 6: 01011[1], try 01011[0]; 010110 > 10103 => 010110
Result: 010110

Prova di correttezza:

Elaboriamo cifra per cifra in questo algoritmo. In ogni passaggio, ci sono cifre il cui valore è già noto e cifre i cui valori non sono ancora noti.

In ogni passaggio, sondiamo la cifra sconosciuta più a sinistra.

Impostiamo quella cifra su "0" e tutte le altre cifre sconosciute su "1". Poiché la cifra da sondare è la più significativa delle cifre sconosciute, il numero risultante è il numero più grande possibile con quella cifra che è uno "0". Se questo numero è inferiore o uguale all'ingresso, la cifra da sondare deve essere un "1".

D'altra parte, il numero risultante è più piccolo di tutti i possibili numeri in cui la cifra da sondare è un "1". Se il numero risultante è maggiore dell'input, la cifra deve essere "0".

Ciò significa che possiamo calcolare una cifra in ogni passaggio.

Codice C.

(Anche il codice C dovrebbe funzionare in C ++):

long long input;
long long result;
long long digit;

... read in input ...

result = 1111111111111111111ll;
digit = 1000000000000000000ll;

while( digit > 0 )
{
    if(result - digit > input)
    {
        result -= digit;
    }
    digit /= 10;
}

... print out output ...

3

Vorrei suggerire un paio di alternative.

I. Incrementare. Consideralo una modifica del metodo @YvesDaoust.

  1. Aumenta N di 1
  2. Espandi il risultato con zero iniziale
  3. Passa dall'ultima alla seconda cifra
    (a) se è inferiore a 2, quindi lascia tutto come è
    (b) altrimenti impostalo su 0 e aumenta il precedente
  4. Ripetere i passaggi 3a, b

Esempi:

1. N = 0 -> 1 -> (0)|(1) -> 1
2. N = 1 -> 2 -> (0)|(2) -> (1)|(0) -> 10
3. N = 101 -> 102 -> (0)|(1)(0)(2) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> 110
4. N = 298 -> 299 -> (0)|(2)(9)(9) -> (0)|(2)(10)(0) -> (0)|(3)(0)(0) -> (1)|(0)(0)(0) -> 1000

Si ottiene il risultato in formato decimale.


II. Dividendo.

  1. Aumenta N di 1
  2. Imposta la somma su 0
  3. Dividi il risultato per 10 per ottenere parti div (D) e mod (M)
  4. Controllare M
    (a) se M supera 1, quindi aumentare D
    (b) altrimenti aumentare la somma di M * 10 k , dove k è il numero di iterazione corrente (che inizia con 0)
  5. Ripetere i passaggi 3,4 fino a quando D è 0

Esempio 1:

1. N = 0 -> N = 1
2. sum = 0
3. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^0 == 1
4. D == 0 -> sum == 1

Esempio 2:

1. N = 1 -> N = 2
2. sum = 0
3. 2/10 -> D == 0, M == 2 -> D = D + 1 == 1
4. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^1 == 10
5. D == 0, sum == 10

Esempio 3:

1. N = 101 -> N = 102
2. sum = 0
3. 102/10 -> D == 10, M == 2 -> D = D + 1 == 11
4. 11/10 -> D == 1, M == 1 -> sum = sum + 1*10^1 = 10
5. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^2 == 10 + 100 == 110
6. D == 0, sum == 110

Esempio 4:

1. N = 298 -> N = 299
2. sum = 0
3. 299/10 -> D == 29, M == 9 -> D = D + 1 == 30
4. 30/10 -> D == 3, M == 0 -> sum = sum + 0*10^1 == 0
5. 3/10 -> D == 0, M == 3 -> D = D + 1
6. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^3 == 1000
7. D == 0, sum == 1000
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.