Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
admitere-informatica-2021 [2021/04/27 13:01]
pdmatei
admitere-informatica-2021 [2021/05/18 12:43] (current)
pdmatei
Line 1: Line 1:
 +====== Lectie filmata online =====
 +
 +==== Varianta 2. Problema 3 ====
 +Un tablou bidimensional ''​a''​ cu n linii si n coloane numerotate de la 1 la n, este simetric fata de diagonala secundara, daca pentru orice pereche de indici (i,j) este adevarata expresia: ​
 +
 +  - ''​a[i][j] = a[j][i]''​
 +  - ''​a[i][j] = a[n+1-j][n+1+i]''​
 +  - ''​a[i][j] = a[n+1-i][n+1-j]''​
 +  - ''​a[i][j] = a[n-j][n-i]''​
 +  - ''​a[i][j] = a[n+1-j][n+1-i]''​
 +  - ''​a[i][j] = a[n+j][n-i]''​
 +==== Solutie ====
 +
 +Intr-o matrice, numerotam cu ''​i''​ liniile, si cu ''​j''​ coloanele. Diagonala secundara poate fi gasita la pozitiile: ''​a[n-i+1,​i]''​ cu i de la 1 la n. Pentru ca matricea sa fie simetrica in raport cu diagonala secundara, in particular, prima linie: ''​a[1,​1] ... a[1,​n]''​ trebuie sa aibe aceleasi valori, element cu element, cu ultima coloana, **transpusa**:​ ''​a[n,​n] ... a[1,​n]''​. Asadar: ''​a[1,​j] = a[n-j+1,​n]'',​ cu j de la 1 la n. Conditia trebuie sa fie adevarata, in continuare, pentru linia 2 si coloana n-1 **transpusa**,​ deci generalizand:​ ''​a[i,​j]=a[n-j+1,​n-i+1]''​. Raspuns corect e).  ​
 +
 +==== Varianta 2. Problema 3 ====
 +Precizati ce valoare are variabila ''​b''​ de tip sir de caractere dupa executarea secventei:
 +
 +<code C>
 +char b[] = "​toc2019"​
 +b[3] = b[3]-1;
 +strcpy(b+5,​b+7);​
 +strcpy(b,​b+3);​
 +</​code>​
 +
 +  - ''​b20''​
 +  - ''​19''​
 +  - ''​20''​
 +  - ''​10''​
 +  - ''​toc''​
 +  - ''​2019''​
 +
 +==== Solutie ====
 +
 +  * Instructiunea ''​b[3]=b[3]-1;''​ modifica sirul in ''​toc1019'';​
 +  * ''​strcpy(b+5,​b+7)''​ modifica sirul in ''​toc10''​ (sirul ''​b+7''​este sirul vid codificat ca ''​\0''​)
 +  * ''​strcpy(b,​b+3)''​ modifica sirul in ''​10''​
 +
 +Raspuns corect ''​10''​ (varianta d).
 +
 +
 +==== Varianta 4. Problema 7 ====
 +
 +Tabloul bidimensional ''​b''​ (cu liniile si coloanele numerotate de la ''​1''​ la ''​n''​) se obtine din tabloul bidimensional ''​a''​ prin rotire cu 90deg la dreapta. Pentru obtinerea unei transformari corecte, secventa:
 +
 +<code C>
 +for (i=1; i<=n; i++)
 +   for (j=1; j<=n; j++)
 +     ...
 +</​code>​
 +trebuie completata cu atribuirea:
 +  - ''​b[i][j]=a[j][i]''​
 +  - ''​b[i][j]=a[j][n-i+1]''​
 +  - ''​b[i][j]=a[n-j+1][n-i+1]''​
 +  - ''​b[i][j]=a[n-i+1][n-j+1]''​
 +  - ''​b[i][j]=a[n-j+1][i]''​
 +  - ''​b[i][j]=a[n-i+1][j]''​
 +
 +==== Solutie ====
 +
 +In rotatia cu 90deg dreapta, linia 1 a matricii devine coloana n, asadar ''​b[i,​n] = a[1,​i]'',​ pentru i de la 1 la n. A doua linie a matricii a devine coloana n-1, deci ''​b[i,​n-1]=a[2,​i]'',​ iar ''​b[i,​1] = a[n,​i]''​. Asadar: ''​b[i,​j]=a[n-j+1,​i]''​. Raspuns corect ''​e)''​.
 +
 +
 +
 +==== Varianta 5. Problema 3 ====
 +
 +Precizati ce valoare se va afisa pe ecran in urma executarii secventei de program urmatoare, stiind ca ''​s''​ este o variabila care memoreaza un sir de caractere, iar ''​i''​ este o variabila de tip intreg.
 +
 +<code C>
 +strcpy(s,"​admitere"​);​
 +for(i=0; i<​strlen(s);​ i++)
 +  if (strchr("​politehnica",​ s[i]))
 +    strcpy(s+i,​s+i+1);​
 +</​code>​
 +
 + - ''​dmt''​
 + - ''​dm''​
 + - ''​dmtr''​
 + - ''​dmr''​
 + - ''​mt''​
 + - ''​mrt''​
 +
 +==== Solutie ====
 +
 +Nu stim capacitatea lui ''​s'',​ insa din faptul ca printre variante nu avem un caz de eroare, prespunem ca este suficienta.
 + - ''​i=0''​. ''​strchr''​ va cauta prima aparitie a lui ''​s[i]'',​ si va intoarce un pointer la ea. Instructiunea din ''​if''​ se va executa doar daca gasim o aparitie. In acest caz ''​a''​ exista si rezultatul va fi: ''​s="​dmitere"''​
 + - ''​i=1''​. String-ul este ''​dmitere''​ -> ''​m''​ nu apare in ''​politehnica'',​ continuam cautarea;
 + - ''​i=2''​. ''​i''​ apare in politehnica:​ ''​*(s+2)="​itere"''​ si noul ''​s''​ va fi ''​dmtere'';​
 + - ''​i=3''​. ''​e''​ apare in politehnica:​ ''​*(s+3)="​ere"''​ si noul ''​s''​ va fi ''​dmtre'';​
 + - ''​i=4''​. ''​e''​ apare in politehnica:​ ''​*(s+4)="​e"''​ si noul ''​s''​ va fi ''​dmtr'';​
 + - ''​i=5''​. Conditia din ''​for''​ nu mai este satisfacuta.
 +
 +Raspuns corect: **c)** (''​dmtr''​)
 +
 +
 +
 +==== Varianta 5. Problema 9 ====
 +
 +Se considera secventa alaturata in care ''​A''​ este un tablou bidimensional cu cinci linii si cinci coloane, numerotate de la ''​1''​ la ''​5'',​ iar ''​x''​ si ''​i''​ sunt variabile de tip intreb. Stiind ca orice element al tabloului este initial egal cu numarul de ordine al liniei pe care se afla, precizati care este valoarea variabilei ''​x''​ dupa executarea secventei de mai jos:
 +
 +<code C>
 +x=0;
 +for (i=1; i<=5; i++)
 +   if (i%2==0) x=x+A[i-1][i];​
 +</​code>​
 +
 +==== Solutie ====
 +
 +Matricea arata in felul urmator:
 +<​code>​
 + 1 1 1 1 1
 + 2 2 2 2 2
 + 3 3 3 3 3
 + 4 4 4 4 4
 + 5 5 5 5 5
 +</​code>​
 +
 +Elementele ''​A[i-1][i]''​ (atentie, cu i de la **2** la **5**), sunt cele **deasupra** diagonalei principale:
 +<​code>​
 + ​1>​1 1 1 1
 + 2 2>2 2 2
 + 3 3 3>3 3
 + 4 4 4 4>4
 + 5 5 5 5 5
 +</​code>​
 +
 +Conditia ''​i%2==0''​ verifica daca ''​i''​ este par (prin urmare, ea nu va fi satisfacuta pentru ''​i=1''​),​ asadar adunam valorile pentru ''​i=2''​ si ''​i=4'',​ deci a doua si a patra valoare de **deasupra diagonalei principale**,​ adica ''​1+3=4''​.
 +
 +==== Varianta 7. Problema 3 ====
 +
 +Se considera doua tablouri unidimensionala ''​A''​ si ''​B''​. Stiind ca ''​A=(7,​10,​12,​18,​20)'',​ iar in urma interclasarii tablourilor ''​A''​ si ''​B'',​ in ordine descrescatoare,​ se obtine tabloul cu elementele ''​(46,​20,​18,​17,​12,​10,​10,​7,​4,​3)''​. Atunci tabloul ''​B''​ poate fi:
 +  - ''​(3,​4,​17,​46)''​
 +  - ''​(3,​4,​10,​46)''​
 +  - ''​(3,​4,​10,​17)''​
 +  - ''​(3,​4,​10,​17,​46)''​
 +  - ''​(46,​17,​4,​3)''​
 +  - ''​(46,​10,​4,​3)''​
 +
 +==== Solutie ====
 +
 +Daca eliminam din rezultat elementele din ''​A'',​ obtinem: ''​(46,​17,​10,​4,​3)'',​ nu neaparat in aceasta ordine. Informatia e suficienta pentru a identifica raspunsul corect, insa putem anticipa si ordinea. Interclasarea se face (conform enuntului) de la ultimul element al fiecarei liste. Observam ca lista rezultat este sortata, ''​A''​ este sortata, deci elementele din ''​B''​ sunt in mod necesar (in acest exemplu) sortate, deci ordinea este ''​(3,​4,​10,​17,​46)''​.
 +
 +
 +
 ====== Rezolvare subiecte admitere - varianta 41 ====== ====== Rezolvare subiecte admitere - varianta 41 ======
  
Line 21: Line 165:
   return f(x, d+1);   return f(x, d+1);
 } }
 +</​code>​
  
 **a)** ''​x==1''​ **b)** ''​x==0''​ **c)** ''​x<​d/​2''​ **d)** ''​x<​d''​ **e)** ''​x>​d''​ **f)** ''​x<​%%=%%d''​ **a)** ''​x==1''​ **b)** ''​x==0''​ **c)** ''​x<​d/​2''​ **d)** ''​x<​d''​ **e)** ''​x>​d''​ **f)** ''​x<​%%=%%d''​
Line 29: Line 174:
  
 Programul de mai sus, testeaza divizibilitatea lui ''​x''​ cu fiecare numar natural ''​d'',​ incepand cu 2. Daca ''​x''​ se divide cu ''​d'',​ procesul se reia cu ''​x/​d''​ si ''​d''​. Cateva observatii: Programul de mai sus, testeaza divizibilitatea lui ''​x''​ cu fiecare numar natural ''​d'',​ incepand cu 2. Daca ''​x''​ se divide cu ''​d'',​ procesul se reia cu ''​x/​d''​ si ''​d''​. Cateva observatii:
 +
 +  * daca un numar ''​x''​ (e.g. 12) se divide cu un ''​d=k*n''​ (e.g. ''​6''​),​ atunci el se divide cu ''​2'',​ iar acest divizor va fi gasit inaintea lui ''​6''​. De aceea este corect sa incrementam cu ''​1''​ pe ''​d'',​ fara a fi nevoie sa luam in considerare doar numerele prime
 +  * daca un numar ''​x''​ (e.g. 9) se divide de mai multe ori cu un ''​d'',​ atunci apelul ''​1+f(x/​d,​d)''​ va contoriza in mod corect de cate ori se divide ''​x''​ cu ''​d''​. Acesta este **exponentul** mentionat in intrebare. Se observa ca dupa ce am //​eliminat//​ din ''​x''​ pe divizorul sau ''​d'',​ putem continua cu un divizor mai mare (nu este necesar sa reluam cautarea de la ''​d=2''​).
 +
 +Algoritmul descris mai sus, poate fi implementat in doua feluri:
 +
 +<code C>
 +int f(int x, int d){
 +  if(x==1) return 0;
 +  if(x%d==0) return 1+f(x/d,d);
 +  return f(x, d+1);
 +}
 +</​code>​
 +
 +In acest caz, cand ''​x==1'',​ numarul a fost deja descompus si toti exponentii au fost contorizati.
 +
 +sau:
 +<code C>
 +int f(int x, int d){
 +  if(x==d) return 1;
 +  if(x%d==0) return 1+f(x/d,d);
 +  return f(x, d+1);
 +}
 +</​code>​
 +
 +In acest caz, cand ''​x==d''​ inseamna ca am intalnit ultima **aparitie** a lui ''​d''​ ca divizor a lui ''​x''​ (garantat sa existe si sa fie gasit de procedura de mai sus). Singurul raspuns cu care programul de mai sus s-ar comporta la fel este ''​x<​=d'' ​
 +
 +===== Exercitiul 3=====
 +
 +Instructiunea care afiseaza cea mai din stanga pozitie unde se afla valoarea intreaga ''​x'',​ sau afiseaza ''​-1'',​ daca ''​x''​ nu apare in tabloul unidimensional ''​a''​ cu ''​n''​ elemente intregi.
 +
 +<code C>
 +// Varianta 1
 +for (i=0 ; i<n && a[i] == x ; i++)
 +    if (i < n) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +<code C>
 +// Varianta 2
 +for (i=0 ; i<n && a[i] != x ; i++)
 +    if (i == n) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +<code C>
 +// Varianta 3
 +for (i=0 ; i<n && a[i] == x ; i++)
 +    if (i == n) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +<code C>
 +// Varianta 4
 +for (i=0 ; i<n && a[i] != x ; i++);
 +    if (i < n) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +<code C>
 +// Varianta 5
 +for (i=0 ; i==n && a[i] != x ; i++);
 +    if (i == n) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +<code C>
 +// Varianta 6
 +for (i=0 ; i<n ; i++)
 +    if (a[i] == x) printf("​%d",​ i);
 +    else printf("​-1"​);​
 +</​code>​
 +
 +==== Solutie ====
 +
 +Consideram ca ''​a''​ contine elementele: ''​1,​2,​3,​2,​4,​5,​1''​ si ca ''​x=2''​. Atunci programul cautat trebuie sa intoarca pozitia ''​1'',​ adica **prima** aparitie a lui ''​2''​ in sir. Analizand cu atentie fiecare varianta:
 +  * //Varianta 1//: va iesi din ''​for''​ daca primul element nu este egal cu ''​x'',​ prin urmare este incorecta.
 +  * //Varianta 2//: va iesi din ''​for''​ cand prima aparitie a lui ''​x''​ in ''​a''​ va fi gasita, insa daca aceasta va fi raportata **doar** daca ''​i==n'',​ deci varianta este gresita.
 +  * //Varianta 3//: aceeasi problema ca //Varianta 1//
 +  * //Varianta 4//: instructiunea ''​for''​ se va executa fara instructiuni interioare pana cand: (i) ''​a[i] == x''​ sau (ii) ''​i==n''​. Daca ''​i<​n'',​ pozitia va fi raportata: **raspuns corect**.
 +  * //Varianta 5//: nu se va intra in ''​for''​ decat daca tabloul are dimensiune 0 (''​i==n''​)
 +  * //Varianta 6//: va afisa **toate** pozitiile pe care se afla ''​x'',​ nu doar prima.
 +
 +===== Exercitiul 4=====
 +Apelul ''​F(7)''​ returneaza:
 +
 +<code C>
 +int F(int N)
 +{  if (N==0) return 1;
 +   ​return F(N-1) + F(N-1);
 +}
 +</​code>​
 + 
 +**a)** 60  **b)** 64  **c)** 120 **d)** 128 **e)** 240 **f)** 256
 +
 +==== Solutie ====
 +
 +Recurenta implementata de program este: $math[F(N)=2*F(N-1)] pt $math[N > 0] si $math[F(0)=1]. Raspunsul asadar trebuie sa fie o putere a lui 2 (ceea ce exclude variantele a) c) d)). Se observa cu usurinta ca $math[F(N)=2^N] asadar raspunsul corect este $math[2^7=128].
 +
 +===== Exercitiul 5=====
 +
 +Se considera un sire de caractere ''​s''​. Stabiliti rezultatul afisarii pe ecran, in urma executarii urmatoarei secvente de program:
 +
 +<code C>
 +char s[15]="​ABCDEFG",​ *p, x[15];
 +p = s;
 +p += 4;        ​
 +strcpy(x,​s+2);  ​
 +strcat(x,​p); ​   ​
 +printf("​%s",​x);​
 +</​code>​
 + 
 +**a)** ''​ABCEFG''​ **b)** ''​BCDEFGDEFG'' ​ **c)** ''​CDEFGEFG'' ​ **d)** ''​CDEFGABCD'' ​ **e)** ​ ''​DEFGDEFG'' ​ **f)** ''​EFGEFG''​
 +
 +==== Solutie ====
 +
 +Varianta c.
 +Slide-uri cu memory model-ul pentru char-uri in C.
 +
 +
 +===== Exercitiul 6=====
 +
 +Precizati care dintre urmatoarele expresii are valoarea ''​1|TRUE''​ daca si numai daca numarul natural ''​n''​ este divizibil cu ''​3''​ si are ultima cifra ''​4''​ sau ''​6''​.
 +
 +A. ''​n/​3==0 && (n%10==4 || n%10 == 6)''​
 +
 +B. ''​n%3==0 && (n%10==4 || n%10 == 6)''​
 +
 +C. ''​(n%3==0 && n%10==4) || (n%3 == 0 && n%10 == 6)''​
 +
 +D. ''​(n%3==0 && n%10==4) || n%10 == 6''​
 + 
 +**a)** ​ nici una **b)** B  **c)** A,B  **d)** B,C **e)** B,D **f)** D,A 
 +
 +==== Solutie ====
 +
 +Discutie despre ''​mod''​ si ''​div''​ si importanta lor pentru CS. Instructiunea:​
 +  * ''​n%3==0''​ verifica daca ''​n''​ este divizibil cu ''​3''​ iar
 +  * ''​n%10==x''​ verifica daca ultima cifra a lui ''​n''​ este egala cu ''​x''​. ​
 +
 +Prioritatea operatorilor (precedenta!).
 +
 +Variantele corecte sunt: B,C. iar raspunsul este d).
 +
 +
 +===== Exercitiul 7=====
 +
 +Se genereaza in ordine lexicografica toate tripletele vocala-consoana-vocala formate cu literele mari ''​A,​B,​C,​D,​E'':​ ''​ABA,​ ABE, ACA, ACE, ADA, ADE, EBA, EBE, ECA, ECE, EDA, EDE''​. Daca se genereaza, folosind aceeasi metoda si aceleasi litere, toate tripletele consoana-vocala-consoana,​ stabiliti care dintre urmatoarele variante este o secventa de triplete generate unul imediat dupa celalalt:
 + 
 +**a)** ​ ''​ACE ADA ADE''​ **b)** ''​BEC BED CAB''​ **c)** ''​BEC CEC DEC''​ **d)** ''​CEA CEB CEC''​ **e)** ''​DAC DAB DEB''​ **f)** ''​DAD DAC DAB'' ​
 +
 +==== Solutie ====
 +
 +Pentru a raspunde corect la o problema, trebuie sa identificam regulile de formare ale tripletelor. In exemplul ilustrat, tripletele sunt:
 +  * vocala-consoana-vocala
 +iar in cerinta tripletele construite vor fi: **consoana-vocala-consoana** asadar:
 +  * primul triplet este ''​BAB''​
 +  * unui triplet $math[x_iy_jz_k] ii urmeaza tripletul $math[x_iy_jz_{k+1}],​ unde litera ''​z_{k+1}''​ este urmatoarea consoana, **daca aceasta exista**
 +  * unui triplet $math[x_iy_jz_n] ii urmeaza tripletul $math[x_iy_{j+1}B],​ unde litera ''​y_{j+1}''​ este urmatoarea vocala, **daca aceasta exista** iar $math[B] este prima vocala.
 +  * unui triplet de forma $math[x_iy_mz_n] ii urmeaza tripletul $math[x_{i+1}AB] unde litera $math[x_{i+1}] este urmatoarea consoana, **daca aceasta exista**, $math[B] este prima consoana, iar $math[A] este prima vocala.
 +
 +
 +Putem incepe prin a elimina urmatoarele variante, din cauza ca tripletii nu respecta forma **consoana-vocala-consoana**:​
 +  ** variantele **a)** si **d)**
 + 
 +Apoi pe baza regulilor de mai sus, putem elimina:
 +   * varianta **c)**, din cauza ca, la primele doua triplete se schimba prima litera fara a se schimba restul.
 +   * varianta **c)**, intre ultimele doua triplete se schimba prima vocala, fara a se modifica ultimele litere
 +   * varianta **e)**, la tripletele ''​DAC DAB''​ nu se respecta ordinea lexicografica la ultima litera
 +   * varianta **f)**, la fel, pentru ''​DAD DAC''​.
 +
 +Varianta corecta este **b)**. ​
 +
 +
 +===== Exercitiul 8=====
 +
 +Se considera numerele naturale ''​m''​ si ''​n''​ ($math[0 \leq m \leq 10, 0 \leq n \leq 10]) si subprogramul ''​Ack(m,​n)'',​ care calculeaza valoarea functiei Ackermann pentru valorile ''​m''​ si ''​n''​. Precizati numarul de apeluri recursive ale subprogramului ''​Ack''​ pentru valorile ''​m=1''​ si ''​n=2'',​ ''​Ack(1,​2)''​.
 +
 +<code C>
 +int Ack (int m, int n)
 +{
 +  if (m == 0)
 +     ​return n+1;
 +  else
 +     if (m > 0 && n == 0)
 +         ​return Ack(m-1,1);
 +         else return Ack(m-1,​Ack(m,​n-1));​
 +}
 +</​code>​
 + 
 +**a)** de 5 ori  **b)** de 6 ori **c)** de 7 ori  **d)** de 8 ori **e)** de 9 ori **f)** de 10 ori 
 +
 +==== Solutie ====
 +
 +Functia lui Ackermann (calculata in program) este primul exemplu de functie:
 +  * **total calculabila** - pentru care putem scrie un algoritm care se termina intotdeauna si care intoarce raspunsul corect (este cel din exercitiu)
 +  * care **nu** este **primitiv-recursiva**. Acest concept are o definitie mai complicata si a fost studiat pentru a afla limitele a ce pot rezolva algoritmii. Informal o functie este **primitiv-recursiva** o putem calcula cu o combinatie de expresii ''​for''​ (la fiecare intrare intr-un ciclu stim exact cate iteratii se vor desfasura).
 +
 +Pentru a identifica numarul de apeluri recursive ''​Ack(1,​2)''​ urmarim programul de mai sus, apel cu apel:
 +<code C>
 +Ack(1,2)
 +Ack(0,​Ack(1,​1))
 +//​contorizam apelul Ack(1,1) din parametru
 +Ack(0,​Ack(0,​Ack(1,​0)))
 +Ack(0,​Ack(0,​Ack(0,​1)))
 +Ack(0,​Ack(0,​2))
 +Ack(0,3)
 +4
 +</​code>​
 +
 +Primul apel nu este recursiv, deci nu il vom numara.
 +Pe a doua linie avem doua apeluri recursive. Apoi ''​Ack(1,​1)''​ va genera inca doua apeluri recursive, iar ''​Ack(1,​0)''​ va genera un singur apel recursiv, urmare caruia apelurile generate anterior vor intoarce. Raspunsul corect este **a)** de cinci ori.
 +
 +===== Exercitiul 9=====
 +
 +Un arbore cu radacina are 359 de noduri numerotate de la 1 la 359. Daca vectorul de tati al acestui arbore (vector notat cu ''​t''​) are proprietatea ca ''​t[i]=[i/​2]'',​ pentru orice ''​i''​ de la 1 la 359, unde ''​[x]''​ reprezinta partea intreaga a numarului ''​x'',​ atunci nuarul de noduri care au exact un descendent direct in acest arbore este:
 +**a)** 178 **b)** 9  **c)** 4  **d)** 3 **e)** 1 **f)** 0 
 +
 +==== Solutie ====
 +
 +
 +
 +
 +===== Exercitiul 1=====
 +
 + 
 +**a)** ​  ​**b)** ​ **c)** exact  **d)** ​ **e)** ​ **f)** ​
 +
 +==== Solutie ====
 +
 +