Numero massimo di caratteri utilizzando i tasti A, Ctrl + A, Ctrl + C e Ctrl + V


106

Questa è una domanda dell'intervista di Google. Non sono in grado di risolverlo da solo. Qualcuno può fare luce?

Scrivere un programma per stampare la sequenza di tasti premuti in modo tale da generare il numero massimo di caratteri "A". Hai il permesso di usare solo 4 tasti: A, Ctrl+ A, Ctrl+ Ce Ctrl+ V. Sono consentite solo N battiture. Tutti i Ctrlcaratteri + sono considerati come una sequenza di tasti, quindi Ctrl+ Aè una sequenza di tasti.

Ad esempio, la sequenza A, Ctrl+ A, Ctrl+ C, Ctrl+ Vgenera due A in 4 sequenze di tasti.

  • Ctrl + A è Seleziona tutto
  • Ctrl + C è Copia
  • Ctrl + V è Incolla

Ho fatto un po 'di matematica. Per ogni N, usando x numeri di A, uno Ctrl+ A, uno Ctrl+ Ce y Ctrl+ V, possiamo generare max ((N-1) / 2) 2 numero di A. Per alcuni N> M, è meglio utilizzare il maggior numero Ctrl+ A's, Ctrl+ Ce Ctrl+ Vsequenze in quanto raddoppia il numero di A di.

La sequenza Ctrl+ A, Ctrl+ V, Ctrl+ Cnon sovrascriverà la selezione esistente. Aggiungerà la selezione copiata a quella selezionata.


In molti editor di testo di ^Asolito è "seleziona tutto", ^Cè "copia", ^Vè "incolla". Questo ti dà un'idea?
Nikolai Fetissov

Intendo il numero di "A". Ad esempio, per N = 7 possiamo stampare 9 A usando i tasti A, A, A, CTRL + A, CTRL + C, CTRL + V, CTRL + V
munda

Uh, sono 7 sequenze di tasti.
John Dibling

@ John "Tutti i caratteri CTRL + sono considerati come una sequenza di tasti, quindi CTRL + A è una sequenza di tasti."
fredley

1
Ho rimosso il tag C ++, questa è puramente una domanda sull'algoritmo e si spera che impedisca ai seguaci di C ++ infelici di votare / votare per chiudere.
Matthieu M.

Risposte:


43

C'è una soluzione di programmazione dinamica. Iniziamo sapendo che 0 chiavi possono farci 0 A. Quindi iteriamo ifino a n, facendo due cose: premendo A una volta e premendo seleziona tutto + copia seguito da incolla jvolte (in realtà j-i-1sotto; nota il trucco qui: i contenuti sono ancora negli appunti, quindi possiamo incollarli più volte senza copia ogni volta). Dobbiamo solo considerare fino a 4 paste consecutive, poiché selezionare, copiare, incollare x 5 equivale a selezionare, copiare, incollare, selezionare, copiare, incollare e quest'ultimo è migliore poiché ci lascia di più negli appunti. Una volta raggiunto n, abbiamo il risultato desiderato.

La complessità potrebbe sembrare O (N), ma poiché i numeri crescono a un tasso esponenziale, in realtà è O (N 2 ) a causa della complessità della moltiplicazione dei grandi numeri. Di seguito è riportata un'implementazione di Python. Occorrono circa 0,5 secondi per calcolare N = 50.000.

def max_chars(n):
  dp = [0] * (n+1)
  for i in xrange(n):
    dp[i+1] = max(dp[i+1], dp[i]+1) # press a
    for j in xrange(i+3, min(i+7, n+1)):
      dp[j] = max(dp[j], dp[i]*(j-i-1)) # press select all, copy, paste x (j-i-1)
  return dp[n]

Nel codice, jrappresenta il numero totale di tasti premuti dopo la nostra nuova sequenza di pressioni di tasti. Abbiamo già ipressioni di tasti in questa fase e 2 nuove pressioni di tasti vanno a seleziona tutto e copia. Quindi stiamo raggiungendo i j-i-2tempi di incolla . Dato che incollare si aggiunge alla sequenza esistente di dp[i] As, è necessario aggiungere 1crearlo j-i-1. Questo spiega il j-i-1nella penultima riga.

Ecco alcuni risultati ( n=> numero di A):

  • 7 => 9
  • 8 => 12
  • 9 => 16
  • 10 => 20
  • 100 => 1391569403904
  • 1,000 => 3268160001953743683783272702066311903448533894049486008426303248121757146615064636953144900245 174442911064952028008546304
  • 50.000 => un numero molto grande!

Sono d'accordo con @SB sul fatto che dovresti sempre affermare le tue ipotesi: il mio è che non devi incollare due volte per raddoppiare il numero di caratteri. Questo ottiene la risposta per 7, quindi a meno che la mia soluzione non sia sbagliata, l'ipotesi deve essere giusta.

Nel chiede qualcuno caso perché non sto controllando le sequenze della forma Ctrl+ A, Ctrl+ C, A, Ctrl+ V: Il risultato finale sarà sempre lo stesso A, Ctrl+ A, Ctrl+ C, Ctrl+ Vche io non considero.


È quello n => resulto result => n? Ad ogni modo, penso che sia sbagliato. Possiamo digitare 9 As con 7 sequenze di tasti. Se è n => resultdecisamente sbagliato. Il numero di As che puoi digitare non può essere inferiore a n.
IVlad

@IVlad It's n => result. Dici "Possiamo digitare 9 come con 7 sequenze di tasti", che è quello che ottengo. Leggi il "trucco" che ho appena modificato.
moinudin

Sembra fantastico, tranne per il fatto che la domanda è trovare il numero massimo di As per un dato numero di sequenze di tasti, non il numero minimo di sequenze di tasti per ottenere un dato numero di As.
Andrew Clark

1
@marcog - la tua notazione è almeno confusa e al massimo sbagliata. nsono le sequenze di tasti che puoi utilizzare. Devi calcolare quanti As puoi digitare npremendo i tasti. Quindi 7 => 7non ha senso.
IVlad

1
Sembra giusto, + 1. Ora vediamo se qualcuno riesce a farlo O(n)o addirittura O(1):).
IVlad

41

Utilizzando la soluzione di marcog ho trovato un pattern che inizia da n=16. Per illustrare questo, ecco le sequenze di tasti per un n=24massimo di n=29, ho sostituito ^ A con S (seleziona), ^ C con C (copia) e ^ V con P (incolla) per la leggibilità:

24: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4     = 1024
25: A,A,A,A,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *   3   *   3   *   3   *   3    = 1296
26: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *   3   *   3   *   3    = 1728
27: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *    4    *   3   *   3    = 2304
28: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P
       4   *    4    *    4    *    4    *    4    *   3    = 3072
29: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4    *    4     = 4096

Dopo un 4 As iniziale, il modello ideale è selezionare, copiare, incollare, incollare, incollare e ripetere. Questo moltiplicherà il numero di As per 4 ogni 5 sequenze di tasti. Se questo schema di 5 sequenze di tasti non può consumare le sequenze di tasti rimanenti da solo, un certo numero di 4 sequenze di tasti (SCPP) consumano le sequenze di tasti finali, sostituendo SCPPP (o rimuovendo una delle paste) se necessario. Le 4 sequenze di tasti moltiplicano il totale per 3 ogni 4 sequenze di tasti.

Usando questo modello qui c'è del codice Python che ottiene gli stessi risultati della soluzione di marcog, ma è O (1) edit : Questo è in realtà O (log n) dovuto all'esponenziazione, grazie a IVlad per averlo sottolineato.

def max_chars(n):
  if n <= 15:
    return (0, 1, 2, 3, 4, 5, 6, 9, 12, 16, 20, 27, 36, 48, 64, 81)[n]
  e3 = (4 - n) % 5
  e4 = n // 5 - e3
  return 4 * (4 ** e4) * (3 ** e3)

Calcolo di e3: ci sono sempre tra 0 e 4 schemi SCPP alla fine dell'elenco di tasti, perché n % 5 == 4ce ne sono 4, n % 5 == 1ci sono 3, n % 5 == 2ci sono 2, n % 5 == 3ci sono 1 e n % 5 == 4ce ne sono 0. Questo può essere semplificato in(4 - n) % 5 .

Calcolo di e4: il numero totale di pattern aumenta di 1 ogni volta n % 5 == 0che si scopre che questo numero aumenta esattamente n / 5. Usando la divisione del piano possiamo ottenere il numero totale di motivi, il numero totale per e4è il numero totale di motivi meno e3. Per chi non ha familiarità con Python, //è la notazione a prova di futuro per la divisione dei piani.


1
Ben fatto! Testato e funziona n=3000, quindi probabilmente è giusto. (Peccato che oggi non abbia più voti: /)
moinudin

5
+1, molto carino. Minore nitpick però: non è proprio O(1)come l' elevazione a potenza non può essere eseguita in tempo costante. È O(log n).
IVlad

2
In realtà, la sequenza "SCPPP" moltiplicherà il numero di caratteri solo per tre: la prima incolla sovrascrive semplicemente il testo selezionato.
Nick Johnson

4
@ Nick Ultima riga della domanda: "La sequenza Ctrl + A, Ctrl + V, Ctrl + C non sovrascriverà la selezione esistente. Aggiungerà la selezione copiata a quella selezionata."
moinudin

2
@marcog Sì, non l'ho notato. Non conosco nessun sistema operativo che si comporti in quel modo, però.
Nick Johnson

15

Ecco come lo approccerei:

  • assume CtrlA= seleziona tutto
  • assume CtrlC= copia la selezione
  • assume CtrlV= incolla la selezione copiata

dato del testo, sono necessarie 4 sequenze di tasti per duplicarlo:

  • CtrlA per selezionare tutto
  • CtrlC per copiarlo
  • CtrlV per incollare (questo incollerà la selezione - STATE LE TUE ASSUNZIONI)
  • CtrlV per incollare di nuovo che lo raddoppia.

Da lì, puoi considerare di fare 4 o 5 A, quindi di ripetere quanto sopra. Nota che fare ctrl + a, c, v, vaumenterà il tuo testo in modo esponenziale man mano che lo fai. Se i colpi rimanenti <4, continua a fare aCtrlV

La chiave per intervistare in luoghi come Google è affermare le tue supposizioni e comunicare il tuo pensiero. vogliono sapere come risolvi i problemi.


6
Buon punto sulla tecnica dell'intervista, ottenere la risposta corretta è meno importante che comunicare chiaramente alla fine!
Fredley

2
Buona risposta. Per l'algoritmo, un errore goloso off-by-two: ACVV-VVVVVmoltiplica per 7, ACVV-ACVV-Vmoltiplica per 6. Quindi Ctrl-V per i colpi rimanenti <6 invece di 4.
Marcel Jackwerth

5

È risolvibile in O (1): Come con i numeri di Fibonacci, c'è una formula per calcolare il numero di As stampati (e la sequenza di tasti):


1) Possiamo semplificare la descrizione del problema:

  • Avere solo [A], [Ca] + [Cc], [Cv] e un buffer di copia-incolla vuoto

è uguale a

  • avendo solo [Ca] + [Cc], [Cv] e "A" nel buffer di copia-incolla.

2) Possiamo descrivere la sequenza di tasti premuti come una stringa di N caratteri da {'*', 'V', 'v'}, dove 'v' significa [Cv] e '*' significa [Ca] e 'V 'significa [Cc]. Esempio: "vvvv * Vvvvv * Vvvv"

La lunghezza di quella stringa è ancora uguale a N.

Il prodotto delle lunghezze delle parole Vv in quella stringa è uguale al numero di As prodotti.


3) Data una lunghezza fissa N per quella stringa e un numero fisso K di parole, il risultato sarà massimo se e solo se tutte le parole hanno lunghezze quasi uguali. La loro differenza a coppie non è superiore a ± 1.

Ora, qual è il numero ottimale K, se viene dato N?


4) Supponiamo di voler aumentare il numero di parole aggiungendo una singola parola di lunghezza L, quindi dobbiamo ridurre L + 1 volte qualsiasi parola precedente di una 'v'. Esempio: "… * Vvvv * Vvvv * Vvvv * Vvvv" -> "… * Vvv * Vvv * Vvv * Vvv * Vvv"

Qual è la lunghezza ottimale della parola L?

(5 * 5 * 5 * 5 * 5) <(4 * 4 * 4 * 4 * 4) * 4, (4 * 4 * 4 * 4)> (3 * 3 * 3 * 3) * 3

=> L'ottimale è L = 4.


5) Supponiamo di avere una N sufficientemente grande per generare una stringa con molte parole di lunghezza 4, ma rimangono poche battute; come dovremmo usarli?

  • Se ne rimangono 5 o più: aggiungi un'altra parola di lunghezza 4.

  • Se sono rimasti 0: Fatto.

  • Se ne rimangono 4: potremmo neanche

    a) aggiungi una parola con lunghezza 3: 4 * 4 * 4 * 4 * 3 = 768.

    b) o aumentare 4 parole alla lunghezza 5: 5 * 5 * 5 * 5 = 625. => Aggiungere una parola è meglio.

  • Se ne rimangono 3: potremmo neanche

    a) o aggiungere una parola di lunghezza 3 regolando la parola precedente da 4 a 3: 4 * 4 * 4 * 2 = 128 <4 * 4 * 3 * 3 = 144.

    b) aumentare 3 parole alla lunghezza 5: 5 * 5 * 5 = 125. => Aggiungere una parola è meglio.

  • Se ne rimangono 2: potremmo neanche

    a) o aggiungere una parola con lunghezza 3 regolando le due parole precedenti dalla lunghezza 4 a 3: 4 * 4 * 1 = 16 <3 * 3 * 3 = 27.

    b) aumentare 2 parole alla lunghezza 5: 5 * 5 = 25. => Aggiungere una parola è meglio.

  • Se è rimasto 1: potremmo neanche

    a) o aggiungi una parola di lunghezza 3 regolando le tre parole precedenti dalla lunghezza 4 alla 3: 4 * 4 * 4 * 0 = 0 <3 * 3 * 3 * 3 = 81.

    b) aumentare una parola alla lunghezza 5: 4 * 4 * 5 = 80. => Aggiungere una parola è meglio.


6) Ora, cosa succede se non abbiamo una "N grande sufficiente" per utilizzare le regole in 5)? Dobbiamo attenerci al piano b), se possibile! Le stringhe per la piccola N sono:

1: "v", 2: "vv", 3: "vvv", 4: "vvvv"

5: "vvvvv" → 5 (piano b)

6: "vvvvvv" → 6 (piano b)

7: "vvv * Vvv" → 9 (piano a)

8: "vvvv * Vvv" → 12 (piano a)

9: "vvvv * Vvvv" → 16

10: "vvvv * Vvvvv" → 20 (piano b)

11: "vvv * Vvv * Vvv" → 29 (piano a)

12: "vvvv * Vvv * Vvv" → 36 (piano a)

13: "vvvv * Vvvv * Vvv" → 48 (piano a)

14: "vvvv * Vvvv * Vvvv" → 64

15: "vvv * Vvv * Vvv * Vvv" → 81 (piano a)

...


7) Ora, qual è il numero ottimale K di parole in una stringa di lunghezza N?

Se N <7 allora K = 1 altrimenti se 6 <N <11 allora K = 2; altrimenti: K = ceil ((N + 1) / 5)

Scritto in C / C ++ / Java: int K = (N<7)?(1) : (N<11)?(2) : ((N+5)/5);

E se N> 10, il numero di parole con lunghezza 3 sarà: K * 5-1-N. Con questo, possiamo calcolare il numero di As stampati:

Se N> 10, il numero di As sarà: 4 ^ {N + 1-4K} · 3 ^ {5K-N-1}


Sembra essere giusto, funziona per gli esempi forniti dalla risposta di @ Andrew, ma anche la tua risposta è O (log N) invece di O (1), giusto?
rsenna

Come potrebbe essere O (log N)? La formula matematica per calcolare il numero di As è calcolata in O (1). L'algoritmo per stampare le sequenze di tasti è O (N) perché ci sono O (N) sequenze di tasti da stampare, o O (1) se si consente di stamparle come espressioni regolari.
comonad

Il calcolo dell'esponenziazione è O (log N) poiché l'esponente sul 4 aumenta con N. Se stampi il numero di As in forma fattorizzata è O (1).
Andrew Clark

Ah ok. Non ho mai pensato di calcolare effettivamente il numero con l'aritmetica dei numeri interi. Sarei interessato solo alla formula o all'approssimazione in virgola mobile. Ma ovviamente, per poterlo confrontare con altri numeri, dovrebbe essere calcolato in modo esatto.
comonad

5

Usare CtrlA+ CtrlC+ CtrlVè un vantaggio solo dopo 4 'A.

Quindi farei qualcosa del genere (in codice pseudo-BASIC, poiché non hai specificato alcun linguaggio appropriato):

// We should not use the clipboard for the first four A's:
FOR I IN 1 TO MIN(N, 4)
    PRINT 'CLICK A'
NEXT
LET N1 = N - 4

// Generates the maximum number of pastes allowed:
FOR I IN 1 TO (N1 DIV 3) DO
    PRINT 'CTRL-A'
    PRINT 'CTRL-C'
    PRINT 'CTRL-V'
    LET N1 = N1 - 3
NEXT

// If we still have same keystrokes left, let's use them with simple CTRL-Vs
FOR I IN N1 TO N
    PRINT 'CTRL-V'
NEXT

modificare

  1. Torna a utilizzare un singolo CtrlVnel ciclo principale.
  2. Aggiunti alcuni commenti per spiegare cosa sto cercando di fare qui.
  3. Risolto un problema con il blocco "prime quattro A".

@ SB: Sto facendo CTRL-V solo per le ULTIME paste. Che è esattamente quello che hai detto nella tua risposta, comunque. Il che significa che la pensiamo in modo simile, quindi non so perché mi stai criticando - o forse mi sto perdendo qualcosa?
rsenna

1
google non specifica mai una lingua corretta in cui scrivere, che mai desideri.
Spooks

3

Sono necessarie 3 sequenze di tasti per raddoppiare il numero di As. Ha senso iniziare a raddoppiare solo quando ne hai 3 o più come già stampati. Vuoi che la tua ultima sequenza di tasti consentita sia a CtrlVper assicurarti di raddoppiare il numero più grande possibile, quindi per allinearla riempiremo ogni battitura in più dopo i primi tre As all'inizio con più As.

for (i = 3 + n%3; i>0 && n>0; n--, i--) {
    print("a");
}

for (; n>0; n = n-3) {
    print("ctrl-a");
    print("ctrl-c");
    print("ctrl-v");
}

Modificare:

Questo è terribile, mi sono completamente superato e non ho considerato più paste per ogni copia.

Modifica 2:

Credo che incollare 3 volte sia ottimale, quando hai abbastanza tasti per farlo. In 5 sequenze di tasti moltiplichi il tuo numero di As per 4. Questo è meglio che moltiplicare per 3 usando 4 sequenze di tasti e meglio che moltiplicare per 5 usando 6 sequenze di tasti. Ho confrontato questo dato dando a ciascun metodo lo stesso numero di sequenze di tasti, abbastanza da far terminare un ciclo allo stesso tempo (60), lasciando che il moltiplicatore 3 faccia 15 cicli, il moltiplicatore 4 faccia 12 cicli e il 5 moltiplicatore fare 10 cicli. 3 ^ 15 = 14.348.907, 4 ^ 12 = 16.777.216 e 5 ^ 10 = 9.765.625. Se sono rimasti solo 4 tasti premuti, fare un moltiplicatore 3 è meglio che incollare altre 4 volte, essenzialmente facendo diventare il moltiplicatore 4 precedente un moltiplicatore 8. Se sono rimasti solo 3 tasti premuti, un moltiplicatore 2 è il migliore.


2

Supponi di avere x caratteri negli appunti e x caratteri nell'area di testo; chiamiamolo "stato x".

Premiamo alcune volte "Incolla" (lo denoto m-1per comodità), poi "Seleziona tutto" e "Copia"; dopo questa sequenza, arriviamo a "state m * x". In questo caso, abbiamo sprecato un totale di m + 1 sequenze di tasti. Quindi la crescita asintotica è (almeno) qualcosa di simile f^n, dove f = m^(1/(m+1)). Credo che sia la massima crescita asintotica possibile, anche se non posso provarlo (ancora).

Provare vari valori di m mostra che il massimo per f si ottiene per m=4 .

Usiamo il seguente algoritmo:

Press A a few times
Press Select-all
Press Copy
Repeat a few times:
    Press Paste
    Press Paste
    Press Paste
    Press Select-all
    Press Copy
While any keystrokes left:
    Press Paste

(non sono sicuro che sia quello ottimale).

Il numero di volte per cui premere A all'inizio è 3: se lo si preme 4 volte, si perde l'opportunità di raddoppiare il numero di A in altre 3 sequenze di tasti.

Il numero di volte in cui premere Incolla alla fine non è superiore a 5: se sono rimaste 6 o più combinazioni di tasti, è possibile utilizzare Incolla, Incolla, Incolla, Seleziona tutto, Copia, Incolla.

Quindi, otteniamo il seguente algoritmo:

If (less than 6 keystrokes - special case)
    While (any keystrokes left)
        A
Else
    First 5 keystrokes: A, A, A, Select-all, Copy
    While (more than 5 keystrokes left)
        Paste, Paste, Paste, Select-all, Copy
    While (any keystrokes left)
        Paste

(non sono sicuro che sia quello ottimale). Il numero di caratteri dopo aver eseguito questo è qualcosa di simile

3 * pow(4, floor((n - 6) / 5)) * (2 + (n - 1) % 5).

Valori di esempio: 1,2,3,4,5,6,9,12,15,18,24,36,48,60,72,96,144,192,240,288, ...


2

Quello che segue usa la seconda modifica dell'OP che incolla non sostituisce il testo esistente.

Nota alcune cose:

  • ^ A e ^ C possono essere considerati un'unica azione che richiede due sequenze di tasti, poiché non ha mai senso eseguirle individualmente. In effetti, possiamo sostituire tutte le istanze di ^ A ^ C con ^ K ^ V, dove ^ K è una chiave singola "taglio" (abbreviamola X). Vedremo che trattare con ^ K è molto più piacevole di ^ A ^ C a due costi.
  • Supponiamo che negli appunti inizi una "A". Allora ^ V (abbreviamolo con Y) è strettamente superiore ad A e possiamo escludere quest'ultimo da ogni considerazione. (Nel problema attuale, se gli appunti iniziano vuoti, in quanto segue sostituiremo semplicemente Y con A invece di ^ V fino alla prima X.)

Ogni ragionevole sequenza di tasti può quindi essere interpretata come un gruppo di Y separati da X, ad esempio YYYXYXYYXY. Indichiamo con V (s) il numero di 'A' prodotte dalla sequenza s. Allora V (nXm) = V (n) * V (m), perché X essenzialmente sostituisce ogni Y in m con V (n) 'A's.

Il problema del copia-incolla è quindi isomorfo al seguente problema: "usare m + 1 numeri che sommano a Nm, massimizza il loro prodotto". Ad esempio, quando N = 6, la risposta è m = 1 e i numeri (2,3). 6 = 2 * 3 = V (YYXYYY) = V (AA ^ A ^ C ^ V ^ V) (o V (YYYXYY) = V (AAA ^ A ^ C ^ V).)

Possiamo fare alcune osservazioni:

Per un valore fisso di m, i numeri da scegliere sono ceil( (N-m)/(m+1) )e floor( (N-m)/(m+1) )(in qualunque combinazione fa funzionare la somma; più specificamente avrai bisogno (N-m) % (m+1) ceilse il resto floors). Questo perché, per a < b,(a+1)*(b-1) >= a*b .

Purtroppo non vedo un modo semplice per trovare il valore di m. Se questa fosse la mia intervista proporrei a questo punto due soluzioni:

Opzione 1. Ripeti tutto il possibile m. Una n log nsoluzione O ( ).

Codice C ++:

long long ipow(int a, int b)
{
  long long val=1;
  long long mul=a;

  while(b>0)
    {
      if(b%2)
    val *= mul;
      mul *= mul;
      b/=2;
    }
  return val;
}

long long trym(int N, int m)
{
  int floor = (N-m)/(m+1);
  int ceil = 1+floor;
  int numceils = (N-m)%(m+1);
  return ipow(floor, m+1-numceils) * ipow(ceil, numceils);
}

long long maxAs(int N)
{
  long long maxval=0;
  for(int m=0; m<N; m++)
    {
      maxval = std::max(maxval, trym(N,m));
    }
  return maxval;
}

Opzione 2. Consenti mdi ottenere valori non interi e di trovare il suo valore ottimale prendendo la derivata di [(N-m)/(m+1)]^mrispetto a me risolvendo la sua radice. Non esiste una soluzione analitica, ma la radice può essere trovata usando, ad esempio, il metodo di Newton. Quindi usa il pavimento e il soffitto di quella radice per il valore di me scegli quello che è meglio.


0
public int dp(int n) 
{
    int arr[] = new int[n];
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    for (int i = 2; i < n - 3; i++) 
    {
        int numchars = arr[i] * 2;
        int j = i + 3;
        arr[j] = Math.max(arr[j], numchars);
        while (j < n - 1) 
        {
            numchars = numchars + arr[i];
            arr[++j] = Math.max(arr[j], numchars);
        }
    }
    return arr[n - 1];
}

0

Ecco il mio approccio e la mia soluzione con il codice di seguito.

Approccio:

Ci sono tre operazioni distinte che possono essere eseguite.

  1. Sequenza di tasti A - Emette un carattere "A"
  2. Sequenza di tasti (Ctrl-A) + (Ctrl-C) - Non restituisce essenzialmente nulla. Queste due sequenze di tasti possono essere combinate in un'unica operazione perché ciascuna di queste sequenze di tasti individualmente non ha senso. Inoltre, questa sequenza di tasti imposta l'output per la successiva operazione di incolla.
  3. Sequenza di tasti (Ctrl-V) - L'output di questa sequenza di tasti dipende in realtà dalla precedente (seconda) operazione e quindi dovremmo tenerne conto nel nostro codice.

Ora, date le tre operazioni distinte e le rispettive uscite, dobbiamo eseguire tutte le permutazioni di queste operazioni.


Assunzione:

Ora, qualche versione di questo problema afferma che la sequenza di sequenze di tasti, Ctrl + A -> Ctrl + C -> Ctrl + V, sovrascrive la selezione evidenziata. Per tenere conto di questo presupposto, è necessario aggiungere solo una riga di codice alla soluzione seguente in cui la variabile stampata nel caso 2 è impostata su 0

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

Per questa soluzione

Il codice seguente stamperà un paio di sequenze e l'ultima sequenzaèla risposta corretta per ogni dato N. es. Per N = 11 questa sarà la sequenza corretta

Con l'ipotesi

A, A, A, A, A, C, S, V, V, V, V,: 20:

Senza l'ipotesi

A, A, A, C, S, V, V, C, S, V, V,: 27:

Ho deciso di mantenere il presupposto per questa soluzione.


Legenda dei tasti:

'AA

"C" - Ctrl + A

"S" - Ctrl + C

"V" - Ctrl + V


Codice:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void maxAprinted(int count, int maxKeys, int op, int printed, int pOutput, int *maxPrinted, char *seqArray)
{
    if(count > maxKeys)
        return;

    if(count == maxKeys)
    {
        if((*maxPrinted) < printed)
        {
            //new sequence found which is an improvement over last sequence
            (*maxPrinted) = printed;

            printf("\n");
            int i;
            for(i=0; i<maxKeys; i++)
                printf(" %c,",seqArray[i]);
        }

        return;
    }

    switch(op)
    {
        case 1:
        //A keystroke
            printed++;

            seqArray[count] = 'A';
            count++;
            break;

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

            seqArray[count] = 'C';
            count++;
            seqArray[count] = 'S';
            count++;
            break;

        case 3:
        //Ctrl-V
            printed = printed + pOutput;

            seqArray[count] = 'V';
            count++;
            break;
    }

    maxAprinted(count, maxKeys, 1, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 2, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 3, printed, pOutput, maxPrinted, seqArray);    
}

int main()
{
    const int keyStrokes = 11;

    //this array stores the sequence of keystrokes
    char *sequence;
    sequence = (char*)malloc(sizeof(char)*(keyStrokes + 1));

    //stores the max count for As printed for a sqeuence
    //updated in the recursive call.
    int printedAs = 0;

    maxAprinted(0, keyStrokes,  1, 0, 0, &printedAs, sequence);

    printf(" :%d:", printedAs);

    return 0;
}    

0

Usando i trucchi menzionati nelle risposte sopra, Matematicamente, la soluzione può essere spiegata in un'equazione come,

4 + 4 ^ [(N-4) / 5] + ((N-4)% 5) * 4 ^ [(N-4) / 5]. dove [] è il massimo fattore intero



0

Ecco la mia soluzione con la programmazione dinamica, senza un ciclo annidato e che stampa anche i caratteri effettivi che dovresti digitare:

N = 52

count = [0] * N
res = [[]] * N
clipboard = [0] * N

def maybe_update(i, new_count, new_res, new_clipboard):
  if new_count > count[i] or (
      new_count == count[i] and new_clipboard > clipboard[i]):
    count[i] = new_count
    res[i] = new_res
    clipboard[i] = new_clipboard

for i in range(1, N):
  # First option: type 'A'.
  # Using list concatenation for 'res' to avoid O(n^2) string concatenation.
  maybe_update(i, count[i - 1] + 1, res[i - 1] + ['A'], clipboard[i - 1])

  # Second option: type 'CTRL+V'.
  maybe_update(i, count[i - 1] + clipboard[i - 1],  res[i - 1] + ['v'],
               clipboard[i - 1])

  # Third option: type 'CTRL+A, CTRL+C, CTRL+V'.
  # Assumption: CTRL+V always appends.
  if i >= 3:
    maybe_update(i, 2 * count[i - 3],  res[i - 3] + ['acv'], count[i - 3])

for i in range(N):
  print '%2d %7d %6d %-52s' % (i, count[i], clipboard[i], ''.join(res[i]))

Questo è l'output ("a" significa "CTRL + A", ecc.)

 0       0      0                                                     
 1       1      0 A                                                   
 2       2      0 AA                                                  
 3       3      0 AAA                                                 
 4       4      0 AAAA                                                
 5       5      0 AAAAA                                               
 6       6      3 AAAacv                                              
 7       9      3 AAAacvv                                             
 8      12      3 AAAacvvv                                            
 9      15      3 AAAacvvvv                                           
10      18      9 AAAacvvacv                                          
11      27      9 AAAacvvacvv                                         
12      36      9 AAAacvvacvvv                                        
13      45      9 AAAacvvacvvvv                                       
14      54     27 AAAacvvacvvacv                                      
15      81     27 AAAacvvacvvacvv                                     
16     108     27 AAAacvvacvvacvvv                                    
17     135     27 AAAacvvacvvacvvvv                                   
18     162     81 AAAacvvacvvacvvacv                                  
19     243     81 AAAacvvacvvacvvacvv                                 
20     324     81 AAAacvvacvvacvvacvvv                                
21     405     81 AAAacvvacvvacvvacvvvv                               
22     486    243 AAAacvvacvvacvvacvvacv                              
23     729    243 AAAacvvacvvacvvacvvacvv                             
24     972    243 AAAacvvacvvacvvacvvacvvv                            
25    1215    243 AAAacvvacvvacvvacvvacvvvv                           
26    1458    729 AAAacvvacvvacvvacvvacvvacv                          
27    2187    729 AAAacvvacvvacvvacvvacvvacvv                         
28    2916    729 AAAacvvacvvacvvacvvacvvacvvv                        
29    3645    729 AAAacvvacvvacvvacvvacvvacvvvv                       
30    4374   2187 AAAacvvacvvacvvacvvacvvacvvacv                      
31    6561   2187 AAAacvvacvvacvvacvvacvvacvvacvv                     
32    8748   2187 AAAacvvacvvacvvacvvacvvacvvacvvv                    
33   10935   2187 AAAacvvacvvacvvacvvacvvacvvacvvvv                   
34   13122   6561 AAAacvvacvvacvvacvvacvvacvvacvvacv                  
35   19683   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvv                 
36   26244   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvv                
37   32805   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvvv               
38   39366  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacv              
39   59049  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvv             
40   78732  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvv            
41   98415  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvvv           
42  118098  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacv          
43  177147  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv         
44  236196  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv        
45  295245  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv       
46  354294 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv      
47  531441 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv     
48  708588 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv    
49  885735 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv   
50 1062882 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv  
51 1594323 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv 

0

Se sono consentiti N colpi di tasto, il risultato è N-3.

A -> N-3

CTRL+ A-> Selezione di questi N caratteri: +1

CTRL+ C-> Copia di quegli N caratteri: +1

Ctrl+ V-> Incollare gli N caratteri. : +1 cioè, (poiché abbiamo selezionato tutti i caratteri usando CTRL+ A) Sostituendo questi caratteri N-3 esistenti con i caratteri N-3 copiati (che sovrascrivono gli stessi caratteri) e il risultato è N-3.


Benvenuto in StackOverflow! Scopri come aggiungere la formattazione del contenuto e possibilmente utilizzare il simbolo della freccia effettivo . Ciò migliorerà la leggibilità della tua risposta!
M. Mimpen
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.