Clasa a VI-a lecția 24 - 7 mar 2019

From Algopedia
Jump to navigationJump to search

Anunțuri

Spuneți NU pescuitului în orice formă

Am aflat că:

  • deși vorbesc despre acest lucru aproape la fiecare curs
  • deși am interzis metode de pescuit pe măsură ce le-am descoperit
  • deși riscul este să vă pierdeți calificarea dacă trișați

cu toate acestea încă descopăr metode prin care să puteți pescui în voie, adică să trișați. În lupta de a ne forma ca oameni, și a încerca să ne desprinde de animăluțe, vom încerca o nouă interdicție:

Descărcarea testelor originale ale problemelor de la concursuri sau de la teme în scopul de a evita penalitățile este interzisă.

Mi-e destul de clar că n-are rost să vorbim vorbe alese, spiritul cercului (care este foarte clar, nu avem voie să pescuim sau să trișăm în nici o formă), ce înseamnă a copia, ce înseamnă a nu da credit, ce înseamnă a trișa sau a fura. Vîrsta sau educația (ambele?) vă împiedică să evoluați. E vina mea, v-am dat prea multă libertate. Dar rezolvăm :-)

Să ne readucem aminte, de ce nu este bine să evităm cu orice preț penalitățile în scopul de a lua 100p? Deoarece:

  • Nu vom învăța să ne creăm propriile teste și să ne testăm corect programele.
  • În orice situație din viața reală nu vor exista teste, ci va trebui să le creăm.
  • La concursuri nu vom avea teste.
  • În acest mod nu vom deveni buni informaticieni, ci doar buni testeri (tester = om care primește un program și niște teste, execută acel program pe acele teste, verifică ca rezultatele să fie corecte, apoi raportează numărul de teste trecute, foarte similar cu ceea ce face varena).
  • Nu în ultimul rînd, pentru că v-am cerut să fiți onești, onestia fiind la mare preț într-o țară unde ea cam lipsește :)

La IQ Academy ne formăm și ca oameni. Sîntem colegi, sîntem o echipă și trebuie să ne respectăm unii pe alții. În vreme ce unii din noi transpiră lucrînd la teme, alții transpiră copiind și trișînd. Unii au un viitor, alții nu.

Întrebare: Cît de grav este trișatul? Răspuns: suficient de grav pentru a pierde calificarea la IQ Academy.

Dragilor: fără scuze! Nu descărcați teste, nu creați conturi false, nu trimiteți surse la alte site-uri în timpul temei sau al concursului, nu trimiteți surse copiate sau cu mici modificări, nu trimiteți surse la arivă în timpul concursurilor și al temelor! Mi-a scăpat vreun mod de a trișa? Dacă da, vă rog să vi-l interziceți singuri. Aveți vreun dubiu asupra unei metode folosite? Întrebați.

Penalizări copiatorilor

Cei care au trimis sursa comisiei la problema faleza, sau o mică modificare a ei, în timpul concursului de acasă de duminică, au fost penalizați, astfel:

  • La o lucrare de control cine copiază ia nota 2.
  • La concurs, cine a copiat a luat 0p pe problema copiată.
  • Problema melci a fost cea ușoară dintre cele două.
  • Cei care au copiat au avut dublul timpului la problema ușoară.
  • Așadar, jumate din punctaj este maximul ce pot primi pe ea. Cu mărinimie! (sperînd că știți ce înseamnă cuvîntul :-)

Cei care au trimis sursa comisiei la problema faleza, sau o mică modificare a ei, la tema 22, au fost penalizați, astfel:

  • Au luat 0p pe problema copiată.
  • Nu am scăzut punctajul la celelalte probleme. Mărinimie!

La următoarea sursă copiată la concurs sau la temă veți pierde calificarea la IQ Academy.

Tema - rezolvări

Problema fact

Comentarii generale

  • Avertismente celor ce nu au trimis nici o soluție la această problemă. Deși problema era grea, puteați lua puncte. Problema a fost de clasa a 9a în 2006. După 13 ani ea poate fi lejer dată la clasa a 6a. Cine: Benescu, Chivu, Cojocariu, Mocanu, Rughiniș, Stoian. Liceul Vianu e în grevă.

Problema melci

Comentarii generale

  • Avertismente celor ce nu au trimis nici o soluție la o problemă destul de ușoară: Calotă, Grecu, Mocanu, Cadîr.

Problema faleza

Comentarii generale

  1. Felicitări celor ce au reușit o soluție de excepție: nimeni, dar problema era foarte grea, nu este o rușine. Așa încît îi felicit pe cei ce au reușit să treacă toate testele cu o soluție proprie, nu copiată: Rughiniș, Togan, Fares, Ilie, Teodorescu.
  2. Mențiuni speciale: toți cei care, deși problema era foarte grea, au muncit să caute propria lor soluție. Fiind mulți nu-i menționez aici, dar îi felicit.
  3. Mulțumiri celor ce m-au ajutat cu comentarii: Badea, Stoian, Asgari.
  4. Unii din voi mi-au dat soluții ce nu iau 100p dar care sînt greu de descifrat. Aș fi încercat să le depanez dacă ați fi pus comentarii. Așa, tot ce pot să vă spun este că sînt greșite, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Puneți vă rog comentarii cu metoda folosită, acolo unde nu este evidentă, iar codul este complicat. Cine: Benescu, Burac, Chivu, Mocanu, Mușat, Ștefănescu, Marcu.
  5. Unii din voi mi-au trimis și la temă soluția din concurs, o soluție care nu funcționează. Aceasta înseamnă că nu v-ați mai gîndit deloc la ea ulterior. Foarte, foarte urît! Cine: Cojocariu, Hossu, Iordache.
  6. Unii din voi ați trimis o soluție copiată după cea a comisiei științifice, atît în concurs, cît și la temă. Precum am avertizat, la varena trimitem doar sursele noastre, nu pe ale altora. La concurs, este cu atît mai grav. Aveți un prim avertisment, după care vă pierdeți calificarea la IQ Academy. Cine: Badea, Asgari, Ipate, Tatomir.
  7. Cei ce ați dat soluția comisiei, vreau să mi-o explicați: Stoian, Petcu, Badea, Voicu, Nicu, Asgari, Ipate, Tatomir.
  8. Avertismente celor ce au trimis la temă o soluție copiată după cea a comisiei științifice la temă. Foarte grav. Avertisment, iar la încă o astfel de abatere vă pierdeți calificarea la IQ Academy: Petcu, Stoian, Voicu, Nicu.
  9. Avertismente celor ce nu au trimis nici o soluție la această problemă: Rebengiuc.

Comentarii individuale

Grupa de dimineață

  • Badea (100p): Mulțumesc pentru comentarii! Codul este cel al comisiei, mai exact al doamnei profesoare Cristina Iordache, ceea ce explică suta de puncte din prima. Mă bucur că l-ai găsit, din comentarii pare că l-ai și înțeles. Dar oare așa e? Sincer, nu cred, deoarece explicația este mult mai adîncă decît ceea ce rezultă din comentariile tale. Avertisment, vezi comentariul 6.
  • Benescu (40p-52p): Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.
  • Burac (36p): Atenție! Confunzi '0' cu 0! Ai declarat vectorul de caractere, foarte frumos! Dar tu scrii
    if ( x == 1 )
      v1[i] = '1';
    else
      v1[i] = '0';

în loc să scrii simplu:

v1[i] = x;

Astfel elementul din vector va lua valoarea zero sau unu ca număr. Un char poate fi un întreg foarte mic, între -128 și 127, nu trebuie neapărat să-l vezi ca pe un caracter. Ce rost are să te complici ținînd cifre '0' sau '1'? Le vei afișa vreodată? Ia exemplu de la numere mari, memorăm cifrele pe char pentru că ele sînt întregi foarte mici, nu le folosim drept caractere. Mai departe, următorul cod este inutil:

  bune1 = bune2 = 0;
  i = 0;
  while ( i < n && ( v1[i] != '1' || v2[i] != '1' ) ) {
    if ( v1[i] == '1' )
      bune1++;
    if ( v2[i] == '1' )
      bune2++;
    i++;
  }

Așa cum ai pus tu condiția de while, tu cauți prima poziție i unde ai '1' pe oricare din cele două dale. Drept urmare, dacă se intră în while rezultă că este obligatoriu ca ambele dale să fie '0'. Deci nici unul din cele două if-uri interioare nu se poate îndeplini, ele sînt inutile. Algoritmul în sine începe undeva la linia 54. Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.

  • Calotă (22p): Bravo, felicitări! Deși scorul tău este mic, metoda folosită este corectă, avansul pe ambele linii și contorizarea pînă unde am ajuns. În plus, sunt ideea și programul tău, ceea ce apreciez foarte mult, problema fiind grea, bravo din nou! Pentru a-l depana, ai următoarele erori de algoritm:
    • În primul caz, (0 0), cele două if-uri nu trebuie imbricate. Ele sînt separate. Cîtă vreme ai (0 0) vei avansa cu ambele poziții, căci nu știi care duce la succes. În loc de:
        if ( poz1 == i - 1 )
          poz1 = i;
        else if ( poz2 == i - 1 )                                            
          poz2 = i;

trebuia:

        if ( poz1 == i - 1 )
          poz1 = i;                                          
        if ( poz2 == i - 1 ) // am scos else-ul, ambele trebuie executate       
          poz2 = i;
  • În cazurile doi și trei, cînd ai (0 1) sau (1 0) trebuia ca în caz că ai dat de o combinație inversă să resetezi ambele poziții, nu doar pe cea opusă. De ce? Deoarece dacă una din poziții ajunge la zi, atunci și cealaltă va ajunge la zi, deoarece ai un 1 alături de poziția curentă. În loc de:
        else{
          placi++;
          poz1 = i;                                                          
        }

trebuia

        else{
          placi++;
          poz1 = poz2 = i; // adaugat faptul ca ambele devin i                  
        }

Cu aceste modificări mici vei lua 100p.

  • Chivu (67p): Atenție la neglijență. Iată ce scrii:
    dub1=0;
    i=0;
    while(i<n && faleza1[i]==0) {
        dub1++;
        i++;
    }

Cînd de fapt tu voiai să calculezi dub1, deci corect era:

    dub1=0;
    while(dub1<n && faleza1[dub1]==0) {
        dub1++;

La fel și pentru dub2. Atenție! Ai o duplicare de cod pentru că ai ținut faleza ca doi vectori. Dacă o țineai ca matrice de două linii nu ai mai fi duplicat codul de citire și căutare, precum și majoritatea codului ce urmează. Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.

  • Cojocariu (30p): soluție identică cu cea din concurs, nu ai gîndit-o deloc la temă, vezi comentariul 5. Foarte urît. Ideea are merit, dar nu ai depanat-o. Dacă continuai ai fi reușit să treci toate testele. În continuare o temă foarte slabă, față de nivelul tău. Nu ai luat 100p nici măcar la factk, unde aveai doar de aplicat formulele din lecție. Avertisment, din nou, în acest fel nu vei rămîne la IQ Academy.
  • Grecu (100p): Atenție! Avertisment de compilare foarte periculos! Nu ignora! Nu poți să citești char cu %d!
  • Hossu (20p): Ai trimis și la temă același cod incomplet de la concurs, vezi comentariul 5. Algoritmul este relativ clar, dar nu funcționează deoarece tu vei merge întotdeauna pe partea unde găsești primul 1. Ca stil, programul tău este aproape dublu, avînd mult cod aproape identic. Dacă la concurs aș mai putea ierta așa ceva, la temă nu.
  • Iordache (55p): Ai trimis și la temă același cod incomplet de la concurs, vezi comentariul 5. Atenție! Avertisment de compilare foarte periculos! Nu ignora! Nu poți să citești char cu %d! Metoda nu este evidentă, dar nu cred că poate fi făcută să funcționeze deoarece tu faci doar două parcurgeri în care încerci să comuți de sus jos sau de jos sus cu informații locale, nu globale. Dacă puneai un comentariu cu metoda folosită puteam să-ți spun mai multe.
  • Mocanu (34p-44p): Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4. Atenție la neglijență crasă! Codul următor:
  for(i=0;i<n;i++){
    fscanf(fin,"%d",&v[0][i]);
  }
  for(i=0;i<n;i++){
    fscanf(fin,"%d",&v[1][i]);
  }

era banal de înlocuit cu:

for ( d = 0; d < 2; d++ )
  for(i=0;i<n;i++){
    fscanf(fin,"%d",&v[d][i]);
  }
  • Mușat (70p): Apreciez că nu ai duplicat cod! Bravo! Ai folosit parametri pentru aceasta, o tehnică validă. Din păcate soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.
  • Nicola (0p): Nimic - scuzat din probleme de sănătate.
  • Petcu (100p): Codul este cel al comisiei, mai exact al doamnei profesoare Cristina Iordache, ceea ce explică suta de puncte din prima. Mă bucur că l-ai găsit, dar l-ai și înțeles? Sincer, nu cred, deoarece explicația este destul de complicată. Avertisment, vezi comentariul 8. Ești la al doilea comentariu de acest fel.
  • Rebengiuc (0p): nimic la temă? De ce? De data aceasta mă voi uita pe sursa trimisă în concurs. Dar este o excepție, nu se va mai întîmpla! Deși nu ai pus comentarii (normal, în timpul concursului), codul este scris clar și ordonat, astfel încît pot să-mi fac o idee. Nu cred că metoda poate fi făcută să funcționeze deoarece tu faci doar două parcurgeri în care încerci să comuți de sus jos sau de jos sus cu informații locale, nu globale. Bravo pentru o sursă clară, scrisă în timpul concursului!
  • Rughiniș (59-95p): O soluție foarte bună, bravo! Nu este ușor de înțeles, ar fi fost bune niște comentarii. E o soluție cu programare dinamică, care vine după multe încercări care se văd comentate în codul tău, ceea ce mă face să mă întreb cît ajutor ai primit la ea, sper că nu mult. Pare că ai și o mică eroare, anume, după ce actualizezi i, actualizarea lui j nu mai e corectă, căci i s-a schimbat. De mirare că funcționează.
  • Stoian (4p-95p): Mulțumesc pentru comentarii! Ultima sursă trimisă nu are nici o legătură cu celelalte. Cînd ai obosit să lucrezi la soluția ta ai trimis o sursă a comisiei, mai exact a doamnei profesoare Cristina Iordache. Mă bucur că ai găsit-o, dar ai și înțeles-o? Sincer, nu cred, deoarece explicația este destul de complicată. Avertisment, vezi comentariul 8. Observație: dacă în loc de doi vectori ai fi folosit o matrice de două linii citirea datelor s-ar fi redus la jumate.
  • Ștefănescu (55p): Te-ai descurcat bine, avînd în vedere greutatea problemei. Pare că tratezi multe cazuri, fără a le acoperi pe toate. Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.
  • Togan: (67p-95p): N-am nici o șansă să înțeleg codul tău. El este repetat de patru ori cu mici diferențe, fără nici un comentariu asupra metodei folosite. Tot ce pot să îți spun este 'felicitări' pentru faptul că treci toate testele. Dacă mă uit pe program voi găsi multe probleme. Dar nu mai am putere, am tot încercat să te conving să gîndești înainte să scrii și apoi să scrii cod curat. Mergi înainte așa, iar cînd te vei poticni să sperăm că te vei putea corecta.
  • Voicu (40p-95p): La temă ai trimis sursa oficială, a comisiei, ca și alți colegi ai tăi. Avertisment, vezi comentariul 8. Din fericire ai trimis o sursă proprie la concurs. De aceea fac o excepție și mă uit pe ea, deși nu e la temă. Programul pare bun. Ai pus și ceva comentarii, care ajută, dar nu asupra metodei folosite. Nu explici ce este cu variabilele A și B, nici nu comentezi ce calculezi în ele. Nu-mi dau seama exact ceea ce faci, dar ce pot să-mi dau seama este că algoritmul pare corect, codul fiind cam dezordonat. Felicitări pentru a-l duce pînă la capăt în timpul concursului, este un algoritm greu!

Grupa de după-amiază

  • Asgari (100p): Mulțumesc pentru comentarii! Codul este cel al comisiei, mai exact al doamnei profesoare Cristina Iordache, ceea ce explică suta de puncte din prima. Mă bucur că l-ai găsit, din comentarii pare că l-ai și înțeles. Dar oare așa e? Sincer, nu cred, deoarece explicația este mult mai adîncă decît ceea ce rezultă din comentariile tale. Avertisment, vezi comentariul 6.
  • Cadîr (28p): Codul este scurt și simplu. Cu toate acestea nu înțeleg ideea, ar fi fost bune comentarii la metodă. Ai doi vectori pe care nu îi folosești, v[] și poz[]. Lucrurile nu prea au sens pe acolo. Dar măcar ai trimis sursa ta, creația ta. Vezi comentariul 4.
  • Dobre (67p-63p): Te-ai descurcat bine, avînd în vedere greutatea problemei. Pare că tratezi multe cazuri, fără a le acoperi pe toate. Soluția ta este greu de descifrat. Aș fi încercat să o depanez dacă ai fi pus comentarii. Așa, tot ce pot să îți spun este că este greșită, dar nu știm dacă algoritmul (metoda) sau doar implementarea. Dacă ar fi să ghicesc după forma codului, cred că algoritmul este greșit. Pune te rog comentarii data viitoare. Vezi comentariul 4.
  • Fares (100p): Apreciez codul original, bravo! Sînt înconjurat de copiatori de surse, tu ai avut curajul să scrii propria sursă și ai și trecut toate testele. Algoritmul tău este greu de înțeles fără comentarii, vezi comentariul general 4. Încerc să înțeleg, dar apoi găsesc tot felul de goange: de ce ai trei linii în mat[][]? Decît poz1 și poz2 nu mai bine le spuneai lin și col? Dar eram în pericol să înțelegem ce scrii, nu? :-) De aceea ai și greșit codul, tu scrii:
  if (poz1 == 100001)
    sol = n;

Dar poz1 e linia, poate fi maxim 1. Desigur voiai să scrii poz2. Eh, ce-i o cifră între prieteni? Mi-e greu să înțeleg metoda. Dar pare corectă. Felicitări, o problemă grea.

  • Ilie (67p-95p): Felicitări pentru o soluție originalã! Nu o înțeleg pe deplin, deoarece nu e evidentă și nu ai comentarii, dar pare rezonabilă. Atenție la cum scrii codul. Pentru a găsi linia unde se află primul 1 tu complici citirea. Mai bine citeai cinstit, apoi căutai linia pe care apare primul 1 astfel:
    i = 0;
    while ( i < n && fal[i][0] + fal[i][1] == 0 )
      i++;
    part = i < n && fal[i][0] == 0 ? 1 : 0;

Era mult mai elegant, mai eficient și mai scurt.

  • Ipate (100p): Codul este aproape identic cu cel al comisiei, mai exact al doamnei profesoare Cristina Iordache. Mă bucur că l-ai găsit, dar l-ai și înțeles? Sincer, nu cred, deoarece explicația este destul de complicată. Mă bucură totuși faptul că l-ai modificat, chiar și minimal, dovedește ceva înțelegere. Vezi comentariul 6.
  • Marcu (5p-59p): Felicitări pentru o soluție originalã! Nu o înțeleg pe deplin, deoarece nu e evidentă și nu ai comentarii referitoare la metodă, dar pare rezonabilă. Cred că pierzi din vedere cazuri. Vezi comentariul 4.
  • Nicu (0p-90p): Ai pornit cu o soluție la temă, apoi ai renunțat complet la ea. Următoarele două soluții provin dintr-o sursă a comisiei. Codul este aproape identic cu cel al comisiei, mai exact al doamnei profesoare Cristina Iordache. Mă bucur că l-ai găsit, dar l-ai și înțeles? Sincer, nu cred, deoarece explicația este destul de complicată. Mă bucură totuși faptul că l-ai modificat, chiar și minimal, dovedește ceva înțelegere. Vezi comentariul 8.
  • Stancu (32p): La o problemă grea apreciez că ai luat 32p pe puterile tale. Ai mers pe o idee clară, simplă, despre care știai că nu este corectă dar va lua puncte, conform restricțiilor enunțului. Prefer atitudinea ta față de a celor ce au preferat să copieze o soluție care nu este a lor. Felicitări. Cred că puteai să iei mai multe puncte dacă aveai încredere în tine și încercai și alte idei.
  • Tatomir (100p): Codul este cel al comisiei, mai exact al doamnei profesoare Cristina Iordache, ceea ce explică suta de puncte din prima. Mă bucur că l-ai găsit, dar oare l-ai și înțeles? Sincer, nu cred, deoarece explicația este complicată. Avertisment, vezi comentariul 6.
  • Teodorescu (100p): Chiar îmi pare rău că nu am înțeles metoda folosită, deoarece nu ai pus comentarii în program. Pare corectă, din ce pot să îmi dau seama în timp limitat. Foarte interesant cum ai factorizat codul, folosind parametrizare! Astfel ai evitat codul duplicat, bravo! A trebuit să folosești un vector de două elemente, bun! E clar că înveți și progresezi, bravo! Atenție la cod neglijent. De exemplu, ai scris:
        if ( cnt_ok[0] < cnt_ok[1] )
            ok = 0;
        else if ( cnt_ok[0] > cnt_ok[1] )
            ok = 1;
        else
            ok = 0;

cînd puteai să combini două ramuri:

        if ( cnt_ok[0] <= cnt_ok[1] )
            ok = 0;
        else
            ok = 1;

La fel și aici, unde nu ai factorizat codul:

    for ( i = 0; i < n; i++ ) {
        fscanf( fin, "%d", &mat[0][i] );
        if ( mat[0][i] == 0 )
            cnt_ok[0]++;
    }
    for ( i = 0; i < n; i++ ) {
        fscanf( fin, "%d", &mat[1][i] );
        if ( mat[1][i] == 0 )
            cnt_ok[1]++;
    }

Era relativ simplu să scrii codul doar o data:

  for ( j = 0; j < 2; j++ )
    for ( i = 0; i < n; i++ ) {
        fscanf( fin, "%d", &mat[j][i] );
        if ( mat[j][i] == 0 )
            cnt_ok[j]++;
    }

Rezolvări aici: [1]

Lecție

<html5media height="720" width="1280">https://www.algopedia.ro/video/2018-2019/2019-03-07-clasa-6-lectie-info-24-720p.mp4</html5media> Lecția constă în discuții despre problemele de la temă. Deoarece sîmbătă este OJI 2019 nu voi organiza concurs duminică.

Sîmbătă este OJI. Este un moment bun să ne reamintim sfaturile pentru olimpiadă.

Mult succes!

Temă

Tema 24 clasa a 6a

Rezolvări aici: [2]