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]
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).
Precizati ce valoare are variabila b
de tip sir de caractere dupa executarea secventei:
char b[] = "toc2019" b[3] = b[3]-1; strcpy(b+5,b+7); strcpy(b,b+3);
b20
19
20
10
toc
2019
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).
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:
for (i=1; i<=n; i++) for (j=1; j<=n; j++) ...
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]
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)
.
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.
strcpy(s,"admitere"); for(i=0; i<strlen(s); i++) if (strchr("politehnica", s[i])) strcpy(s+i,s+i+1);
- dmt
- dm
- dmtr
- dmr
- mt
- mrt
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
)
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:
x=0; for (i=1; i<=5; i++) if (i%2==0) x=x+A[i-1][i];
Matricea arata in felul urmator:
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
Elementele A[i-1][i]
(atentie, cu i de la 2 la 5), sunt cele deasupra diagonalei principale:
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
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
.
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)
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)
.
Numim graf complementar al unui graf neorientat $ G$ graful neorientat $ G_1$ cu aceeasi multime a nodurilor ca si $ G$ si cu proprietatea ca doua noduri sunt adiacente in $ G_1$ daca si numai daca nu sunt adiacente in $ G$ . Daca $ G$ are $ n$ noduri si $ m$ muchii, cate muchii are $ G_1$ .
a) exact n(n-1)/2-m
b) exact n-m
c) exact (n-1)/2
d) minimum n(n-1)/2-m
e) minimum n-m
f) maximum n(n-1)/2-m
Explicatii: ce este un graf neorientat, complementar, complet la ce se refera adiacenta.
Rezolvare: Intr-un graf complet se gasesc n(n-1)
muchii orientate, cu conditia ca o muchie sa nu poata avea acelasi nod ca sursa/destinatie. Asadar avem n(n-1)/2
muchii neorientate. Daca in $ G$ se gasesc $ m$ muchii, atunci in $ G_1$ se vor gasi $ \frac{n(n-1)}{2}-m$ muchii.
Cu ce expresie trebuie completata secventa lipsa (marcata prin …
) din functia urmatoare, pentru ca f(x,2)
sa aiba ca rezultat suma exponentilor factorilor primi ce intra in descompunerea lui x
?
int f(int x, int d){ if(...) return 1; if(x%d==0) return 1+f(x/d,d); return f(x, d+1); }
a) x==1
b) x==0
c) x<d/2
d) x<d
e) x>d
f) x<=d
Context: numerele prime compun toate numerele naturale (comparatie cu tabelul lui Mendeleev). Factorii primi sunt acele numere prime care compun un numar. Iar exponentii sunt puterile la care acesti factori se afla. Gauss, a demonstrat in aprox. 1800, ca fiecare numar natural are o descompunere unica in factori primi.
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:
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 primex
(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:
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); }
In acest caz, cand x==1
, numarul a fost deja descompus si toti exponentii au fost contorizati.
sau:
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); }
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
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.
// Varianta 1 for (i=0 ; i<n && a[i] == x ; i++) if (i < n) printf("%d", i); else printf("-1");
// Varianta 2 for (i=0 ; i<n && a[i] != x ; i++) if (i == n) printf("%d", i); else printf("-1");
// Varianta 3 for (i=0 ; i<n && a[i] == x ; i++) if (i == n) printf("%d", i); else printf("-1");
// Varianta 4 for (i=0 ; i<n && a[i] != x ; i++); if (i < n) printf("%d", i); else printf("-1");
// Varianta 5 for (i=0 ; i==n && a[i] != x ; i++); if (i == n) printf("%d", i); else printf("-1");
// Varianta 6 for (i=0 ; i<n ; i++) if (a[i] == x) printf("%d", i); else printf("-1");
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:
for
daca primul element nu este egal cu x
, prin urmare este incorecta.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.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.for
decat daca tabloul are dimensiune 0 (i==n
)x
, nu doar prima.
Apelul F(7)
returneaza:
int F(int N) { if (N==0) return 1; return F(N-1) + F(N-1); }
a) 60 b) 64 c) 120 d) 128 e) 240 f) 256
Recurenta implementata de program este: $ F(N)=2*F(N-1)$ pt $ N > 0$ si $ 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 $ F(N)=2^N$ asadar raspunsul corect este $ 2^7=128$ .
Se considera un sire de caractere s
. Stabiliti rezultatul afisarii pe ecran, in urma executarii urmatoarei secvente de program:
char s[15]="ABCDEFG", *p, x[15]; p = s; p += 4; strcpy(x,s+2); strcat(x,p); printf("%s",x);
a) ABCEFG
b) BCDEFGDEFG
c) CDEFGEFG
d) CDEFGABCD
e) DEFGDEFG
f) EFGEFG
Varianta c. Slide-uri cu memory model-ul pentru char-uri in C.
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
Discutie despre mod
si div
si importanta lor pentru CS. Instructiunea:
n%3==0
verifica daca n
este divizibil cu 3
iarn%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).
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
Pentru a raspunde corect la o problema, trebuie sa identificam regulile de formare ale tripletelor. In exemplul ilustrat, tripletele sunt:
iar in cerinta tripletele construite vor fi: consoana-vocala-consoana asadar:
BAB
z_{k+1}
este urmatoarea consoana, daca aceasta existay_{j+1}
este urmatoarea vocala, daca aceasta exista iar $ B$ este prima vocala.Putem incepe prin a elimina urmatoarele variante, din cauza ca tripletii nu respecta forma consoana-vocala-consoana:
Apoi pe baza regulilor de mai sus, putem elimina:
DAC DAB
nu se respecta ordinea lexicografica la ultima literaDAD DAC
.Varianta corecta este b).
Se considera numerele naturale m
si n
($ 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)
.
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)); }
a) de 5 ori b) de 6 ori c) de 7 ori d) de 8 ori e) de 9 ori f) de 10 ori
Functia lui Ackermann (calculata in program) este primul exemplu de functie:
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:
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
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.
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
a) b) c) exact d) e) f)