CEL MAI MARE NUMĂR [OLI Cluj 2010]

C/C++ este un limbaj multi-paradigmă de nivel mediu, orientat pe obiecte, folosit pe scară largă în industria software datorită echilibrului dintre viteză şi complexitate. Dacă ai nelămuriri în legătură cu acest limbaj sau vrei să ne înveți ceva chiar tu, intră aici.

CEL MAI MARE NUMĂR [OLI Cluj 2010]

Postby jolgau » 10 Jan 2012, 15:13

Enunt :
    Petrică are n cartonaşe cu numere naturale distincte. El vrea să găsească cel mai mare număr care se poate forma prin unirea a două cartonaşe diferite. Două cartonaşe se pot uni dacă primul cartonaş se termină cu cifra cu care începe al doilea cartonaş. Ajutaţi-l pe Petrică să găsească numărul dorit.

    Petrică are n=5 cartonaşe
    2393 1963 1971 120 34
    Cel mai mare număr care se poate forma este 19711963

    Date de intrare
    Fişierul de intrare NUMAR.IN conţine pe prima linie numărul de cartonaşe n, iar pe a doua linie n valori naturale reprezentând numerele de pe cele n cartonaşe. Valorile de pe linia a doua sunt separate prin câte un spaţiu.

    Date de ieşire
    Fişierul de ieşire NUMAR.OUT conţine cel mai mare număr care se poate forma prin unirea a două cartonaşe astfel încât al doilea cartonaş începe cu cifra cu care se termină primul cartonaş. Dacă nu există soluţie atunci se afişează 0.

    Restricţii şi precizări
    • 2 ≤ n≤ 10000, n număr natural
    • Numerele de pe cartonaşe sunt numere naturale cu valori mai mici sau egale cu 20000.

    Exemple
    NUMAR.IN
    5
    2393 1963 1971 120 34
    NUMAR.OUT
    19711963
    Explicaţie
    Se unesc cartonaşele ce conţin numerele 1971 şi 1963
    NUMAR.IN
    2
    456 89
    NUMAR.OUT
    0
    Explicaţie
    Cele două cartonaşe nu se pot uni în modul cerut de problemă

    Timp maxim de execuţie/test : 1 secundă


Am reusit sa rezolv aceasta problema dar 4 dintre teste depasesc timpul de executie.
  1. #include<iostream>
  2. #include<fstream>
  3. using namespace std;
  4.  
  5. int putere(int nrcif)
  6. {
  7. int i,m=1;
  8. for(i=1; i<nrcif; i++)
  9.     m = m * 10;
  10. return m;  
  11. }
  12.  
  13. int main()
  14. {
  15. long long i,n,j,v[10000],max=0,nrcif=0,x,c,n1,n2;
  16.  
  17. ifstream f("numar.in");
  18. ofstream g("numar.out");
  19.  
  20. f>>n;
  21. for(i=1; i<=n; i++)
  22.    f>>v[i];
  23.    
  24.  
  25. //REZOLVARE
  26. for(i=1; i<=n; i++)
  27.    {
  28.    for(j=1; j<=n; j++)
  29.        {
  30.        x = v[j];
  31.        while(x != 0)
  32.             {
  33.             x=x/10;
  34.             nrcif++;      
  35.             }
  36.        c = putere(nrcif);
  37.        if(v[i] % 10 == v[j] / c && i != j)
  38.           {
  39.           if(v[i] + v[j] > max)
  40.              {
  41.              max = v[i] + v[j];
  42.              n1 = v[i];
  43.              n2 = v[j];
  44.              }    
  45.           }
  46.        nrcif=0;
  47.        }            
  48.    }
  49.    
  50. if(max == 0)
  51.   g<<0;
  52. else
  53.   g<<n1<<n2;
  54.  
  55. f.close();
  56. g.close();
  57.  
  58. return 0;    
  59. }
  60.  


Imi puteti da niste sfaturi ca sa mai reduc din cod si sa functioneze mai repede varog frumos?
0,0p / 0 votes
User avatar
jolgau
Bit
 
Joined: 11 Dec 2010
Status: 0

Re: CEL MAI MARE NUMĂR [OLI Cluj 2010]

Postby eni4ever » 10 Jan 2012, 17:08

Ai putea încerca să rezolvi problema cu șiruri în loc de metoda acutală de calcul cu puterii. O altă abordare productivă ar fi să încarci elementele într-un vector ordonat. În felul acesta ai mai reduce din complexitate.

Conform simulărilor, varianta cu șiruri ar fi în medie cu 130% mai rapidă.
Algoritmul lui jolgau s-a executat in 776243 nano secunde
Algoritmul cu siruri s-a executat in 299634 nano secunde
t(jolgau)/t(siruri) = 2.59064
0,0p / 0 votes
Image

"Rațiunea vine în umbre scurte numite suferințe." Victor Adăscăliței
"Bender: Anything less than immortality is a complete waste of time.
Zoidberg: Then suicide it is! Step into my office ..." Futurama S06E06
User avatar
eni4ever
DWord
 
Joined: 03 Jan 2010
Location: Timișoara
Status: 57.83

Re: CEL MAI MARE NUMĂR [OLI Cluj 2010]

Postby Mihai » 10 Jan 2012, 18:28

Nu ai nevoie să optimizezi codul (deși într-adevăr e loc de ceva optimizări) ci să găsești un algoritm mai eficient. Problema poate fi rezolvată în O(n). Pentru asta, formezi două tablouri, maxInceput și maxSfarsit, unde maxInceput[i] va reprezenta numărul maxim dintre cele citite care începe cu cifra i (analog, în maxSfarsit[i] vei salva numărul maxim care se termină cu cifra i). Folosești apoi cele două tablouri pentru determinarea numărului maxim care poate fi obținut (las asta în seama ta).
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: CEL MAI MARE NUMĂR [OLI Cluj 2010]

Postby jolgau » 10 Jan 2012, 19:15

Multumesc, acuma o sa o implementez.
0,0p / 0 votes
User avatar
jolgau
Bit
 
Joined: 11 Dec 2010
Status: 0


Return to C / C++

Who is online

Users browsing this forum: No registered users and 0 guests

cron