Salve a tutti, volevo sapere se oltre all’utilizzo delle funzioni del C per lettura e scrittura su file che risultano più veloci, cè un modo di ottimizzare ulteriormente l’algoritmo di ricerca della somma massima??
Io semplicemente tengo 2 vettori da 2 elementi. un vettore per contere i due numeri pari più grandi (dato che pari + pari = pari) ed un vettore per contenere i due numeri dispari più grandi (dato che dispari + dispari = pari)
Solo che il fatto di dover swappare i vari richiede un po di tempo.
Il codice qui sotto da 100/100 ma nel test case 20 impiega 0.030
Nota: le funzioni di lettura del C++ non sono sempre più lente. Il fatto è che cin/cout mantengono una “sincronizzazione” con scanf/print che ti permette di leggere/scrivere in un modo o nell’altro, interscambiabilmente. Se esegui questa riga, prima di leggere/scrivere, disattivi la suddetta sincronizzazione:
ios_base::sync_with_stdio(false);
A volte in questo modo cin/cout risultano addirittura più veloci di scanf/printf (ma a quel punto devi stare attento a NON mischiare mai scanf/printf)
Disattivando la sincronizzazione ho miglioramenti solo quando utilizzo cin e cout giusto?? Nel mio caso che uso solo l’ fstream non avrei alcun cambiamento?
Poi oltre alla questione della velocità di input/output che è interessante, riguardo l’algoritmo stesso, c’è un modo migliore per risolvere il problema?
Non succedono cose belle, suppongo... Nella peggiore delle ipotesi ti ritroveresti ad avere risultati corretti sul tuo PC ma errati sul server (o viceversa).
Disattivando la sincronizzazione ho miglioramenti solo quando utilizzo cin e cout giusto?? Nel mio caso che uso solo l' fstream non avrei alcun cambiamento?
simone.pri
Credo di sì... Ma comunque tieni conto che la lettura da file sta diventando sempre più una cosa superflua. Ormai alle IOI e anche alle OII viene richiesto solo di implementare una certa funzione, ad esempio int solve(int N, int input[]), che restituisca il risultato corretto, quindi l'input ti viene già dato, non devi leggerlo.
Poi oltre alla questione della velocità di input/output che è interessante, riguardo l'algoritmo stesso, c'è un modo migliore per risolvere il problema?
simone.pri
Beh, in termini di complessità direi che non puoi fare meglio di un algoritmo lineare (il tuo è lineare vero?), e in genere (alle olimpiadi) se hai la complessità giusta non è necessario stare ad ottimizzare (infatti i time limit sono molto superiori del necessario, e la "soluzione campione" generalmente passa con parecchio margine di tempo).
Al posto di usare l'operazione del resto per vedere se è pari o dispari, puoi usare l'AND bit a bit, in questo modo:
if(temp&1)
//dispari
else
//pari
Lawliet
Nah, io non starei a fare queste "ottimizzazioni"... Il compilatore spesso e volentieri sa già farle (e le fa) di suo :)
wil93
Vero e facilmente verificabile sul campo.
Questo è il (minimo?) codice C++ che lo dimostra:
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; i++)
{
if (i % 2) cout << “Even”;
if (i & 1) cout << “Even, fastly?”;
}
}
Il compilatore g++ traduce entrambe le condizioni con l’istruzione assembly