Sunteți pe pagina 1din 8

Universitatea POLITEHNICA din București

Admitere Anticipată Informatică – Facultatea de Automatică și Calculatoare

Aprilie 2023
Rezolvare propusă de Alex Deonise – costin.deonise@stud.acs.upb.ro

1. Se dau definițiile înregistrărilor de mai jos și variabila licee:


Varianta C/C++
struct Data {int zi; int luna; int an;};
struct Elev {struct Data dataNasterii; char nume[256];};
struct Clasa {int numar; char litera; struct Elev elevi[30];};
struct Liceu {int numar; struct Clasa clase[28];};

struct Liceu licee[10];

Varianta Pascal
type
Data = record zi, luna, an: Integer; end;
Elev = record dataNasterii: Data; nume: string[255]; end;
Clasa = record numar: Integer; litera: Char; elevi: array[0..29] of Elev; end;
Liceu = record numar: Integer; clase: array[0..27] of Clasa; end;

var licee: array[0..9] of Liceu;


Care este numărul maxim de elevi care pot fi stocați în variabila licee? (9 pct.)
a) 280; b) 840; c) 300; d) 2800; e) 8400; f) 256
Rezolvare:

Structurile de date din codul dat descriu o ierarhie de date care este formată din licee, clase și elevi. Fiecare liceu are
un număr asociat și un vector de clase. Fiecare clasă are un număr și o literă asociată și un vector de elevi. Fiecare elev
are un nume și o dată de naștere asociată, reprezentată de o structură de tipul Data.
În C/C++, structurile sunt definite cu cuvântul cheie "struct", iar vectorii sunt definiți cu ajutorul colțurilor. În Pascal,
se folosește cuvântul cheie "record" pentru structuri și cuvântul cheie "array" pentru vectori, specificându-se intervalul
de indecși. Pentru a calcula numărul maxim de elevi care pot fi stocați în variabila "licee", trebuie să înmulțim numărul
maxim de licee cu numărul maxim de clase pe care le poate avea un liceu și cu numărul maxim de elevi pe care îi poate
avea o clasă.
Astfel, putem vedea că fiecare liceu poate avea maxim 28 de clase, iar fiecare clasă poate avea maxim 30 de elevi. Deci,
numărul maxim de elevi care pot fi stocați în variabila "licee" este:
10 (numărul maxim de licee) * 28 (numărul maxim de clase pe liceu) * 30 (numărul maxim de elevi pe clasă) = 8400.
Prin urmare, răspunsul corect este e) 8400.

2. Un an este bisect dacă este divizibil cu 400, sau este divizibil cu 4 dar nu cu 100. Care din următoarele expresii verifică
această proprietate, considerând an o variabilă de tip întreg? (9 pct.)
a) C/C++: an % 400 == 0 && an % 4 == 0 && an % 100 == 0;
Pascal: (an mod 400 = 0) and (an mod 4 = 0) and (an mod 100 = 0);
b) C/C++: an % 400 == 0 || (an % 4 == 0 || an % 100 != 0);
Pascal: (an mod 400 = 0) or ((an mod 4 = 0) or (an mod 100 <> 0));
c) C/C++: an % 400 == 0 && (an % 4 == 0 || an % 100 != 0);
Pascal: (an mod 400 = 0) and ((an mod 4 = 0) or (an mod 100 <> 0));
d) C/C++: an % 400 == 0 && (an % 4 == 0 && an % 100 != 0);
Pascal: (an mod 400 = 0) and ((an mod 4 = 0) and (an mod 100 <> 0));
e) C/C++: an % 400 == 0 || (an % 4 == 0 && an % 100 != 0);
Pascal: (an mod 400 = 0) or ((an mod 4 = 0) and (an mod 100 <> 0));
f) C/C++: an % 4 == 0;
Pascal: an mod 4 = 0;
Rezolvare:

Definiția de an bisect spune că un an este bisect dacă:


• este divizibil cu 400, SAU
• este divizibil cu 4 dar nu cu 100.
Pentru a verifica această proprietate pentru o variabilă an de tip întreg, putem folosi expresii logice care combină
operatorii de comparare și logici pentru a evalua această condiție. Să analizăm fiecare opțiune în parte:
a) C/C++: an % 400 == 0 && an % 4 == 0 && an % 100 == 0;
Pascal: (an mod 400 = 0) and (an mod 4 = 0) and (an mod 100 = 0);
Această opțiune verifică dacă an este divizibil cu 400, divizibil cu 4 și divizibil cu 100. Acesta nu este corect, deoarece
pentru a fi bisect, anul trebuie să fie divizibil cu 100 doar dacă nu este divizibil cu 400, ceea ce nu este verificat în
această expresie. De asemenea, operatorul && (și) este folosit în loc de || (sau) pentru a verifica divizibilitatea cu 4 și
100.

b) C/C++: an % 400 == 0 || (an % 4 == 0 || an % 100 != 0);


Pascal: (an mod 400 = 0) or ((an mod 4 = 0) or (an mod 100 <> 0));
Această opțiune verifică dacă an este divizibil cu 400 sau dacă este divizibil cu 4 sau nu este divizibil cu 100. Această
expresie nu este corectă.

c) C/C++: an % 400 == 0 && (an % 4 == 0 || an % 100 != 0);


Pascal: (an mod 400 = 0) and ((an mod 4 = 0) or (an mod 100 <> 0));
Această opțiune verifică dacă an este divizibil cu 400 și este divizibil cu 4 sau nu este divizibil cu 100. Ar fi trebuit sa
fie îndeplinită una din cele 2, deci din start operatorul && (și) ar trebui înlocuit de || (sau).

d) C/C++: an % 400 == 0 && (an % 4 == 0 && an % 100 != 0);


Pascal: (an mod 400 = 0) and ((an mod 4 = 0) and (an mod 100 <> 0));
Această opțiune verifică dacă an este divizibil cu 400 și divizibil cu 4 și este divizibil cu 100. Acesta nu este corect,
deoarece pentru a fi bisect, anul trebuie să fie divizibil cu 100 doar dacă nu este divizibil cu 400.

e) C/C++: an % 400 == 0 || (an % 4 == 0 && an % 100 != 0);


Pascal: (an mod 400 = 0) or ((an mod 4 = 0) and (an mod 100 <> 0));
Această opțiune verifică dacă an este divizibil cu 400 sau divizibil cu 4 și nedivizibil cu 100. Acesta este corectă.

f) C/C++: an % 4 == 0;
Pascal: an mod 4 = 0;
Această opțiune verifică dacă an este divizibil cu 4.
3. Se dau m1 greutăți de k1 kg fiecare și m2 greutăți de k2 kg fiecare. Cel mai bun candidat la un concurs a scris un program
corect care stabilește modurile în care poate fi echilibrată o balanță având pe talerul din stânga o greutate X dată și
afișează numărul de soluții posibile. Greutățile pot fi puse pe ambele talere. Programul citește la rulare numerele
naturale m1 k1 m2 k2 X în această ordine. Ce afișează programul pentru trei rulări succesive: rulare 1: 5 2 5 1 4, rulare
2: 5 2 5 1 11, rulare 3: 5 2 5 1 20. (9 pct.)
a) 10 5 0; b) 20 7 0; c) 20 7 1; d) 10 10 0; e) 10 7 0; f) 20 5 0.
Rezolvare:

Folosim următorul cod:


#include <iostream>

using namespace std;

int main() {
int m1, k1, m2, k2, X;
cin >> m1 >> k1 >> m2 >> k2 >> X;

int count = 0;
for (int v1 = 0; v1 <= m1; v1++) {
for (int w1 = 0; w1 <= m1 - v1; w1++) {
for (int v2 = 0; v2 <= m2; v2++) {
for (int w2 = 0; w2 <= m2 -v2; w2++) {
if (X + v1 * k1 + v2 * k2 == w1 * k1 + w2 * k2) {
count++;
}
}
}
}
}
cout << count << endl;
return 0;
}
Unde:
• v1 – numărul de k1 care se pot pune pe talerul din stânga;
• v2 – numărul de k2 care se pot pune pe talerul din dreapta;
• w1 – numărul de k1 care se pot pune pe talerul din dreapta;
• w2 – numărul de k2 care se pot pune pe talerul din stânga;
În fiecare iterație, programul calculează greutatea totală de pe ambele talere, pe baza numărului de greutăți și a valorii
acestora. De asemenea, verifică și dacă balanța este echilibrată (egală cu X). Dacă da, se incrementează variabila
"count", care reprezintă numărul de soluții posibile. La final, programul afișează numărul de soluții posibile, calculat
prin variabila "count".
Iar pentru cele 3 rulari ale codului se vor obtine valorile: 20 7 0.

4. Se consideră șirul 1 2 3 4 5 6. În câte moduri se pot aranja elementele șirului astfel încât în șirurile rezultate niciunul
din elemente să nu se afle pe poziția inițială. (9 pct.)
6! 6! 6! 6! 6! 6!
a) 1!
− 2! + 3! − 4! + 5! − 6!;

b) 6!;
6! 6! 6! 6! 6! 6! 6!
c) 0!
− 1! + 2! − 3! + 4! − 5! + 6!;
6! 6! 6! 6! 6! 6!
d) 1!
+ 2! − 3! + 4! − 5! + 6!;
e) 6! − 5!;
f) 6! − 4!.
Rezolvare:

Pentru a rezolva această problemă de combinatorică, trebuie să găsim numărul de aranjamente în care niciunul din
elementele șirului nu se află pe poziția inițială. Pentru a găsi acest număr, putem utiliza Principiul Includerii și
Excluderii. Principiul enunță faptul că fiind date n mulțimi finite, relația de mai jos este adevarată:

Numărul total de aranjamente fără restricții ale șirului este 6!, din care vom scădea reuniunea tuturor permutărilor
„proaste” folosind formula:
Deci răspunsul corect este dat de varianta c).

5. Precizați care este instrucțiunea prin care variabilei y i se atribuie numărul format din ultimele două cifre ale oricărui
număr natural de 3 cifre nenule, memorat în variabila întreagă x. (9 pct.)
a) C/C++: y = (x%100)%10; Pascal: y := (x mod 100) mod 10;
b) C/C++: y = (x-x%10)%100; Pascal: y := (x - x mod 10) mod 100;
c) C/C++: y = (x-x/10)%100; Pascal: y := (x - x div 10) mod 100;
d) C/C++: y = x%100; Pascal: y := x mod 100;
e) C/C++: y = x/100; Pascal: y := x div 100;
f) C/C++: y = (x%10)%10; Pascal: y := (x mod 10) mod 10;
Rezolvare:

Pentru a lua ultima cifră a unui număr avem nevoie de restul împărțirii sale la 10 -> x % 10.
Dacă dorim sa luăm ultimele doua cifre, avem nevoie de restul împărțirii la 100 -> x % 100.
6. Câte cicluri elementare distincte cu 4 muchii există într-un graf neorientat complet cu 6 noduri? Două cicluri sunt
distincte dacă diferă prin cel puțin o muchie. (9 pct.)
a) 45; b) 180; c) 72; d) 24; e) 360; f) 120.
Rezolvare:

Pentru a rezolva această problemă, putem porni de la definirea unui ciclu elementar într-un graf neorientat: Un ciclu
elementar este un șir de noduri și muchii care începe și se termină în același nod și care nu trece prin niciun alt nod
de două ori. În acest caz, avem 6 noduri din care trebuie să alegem 4 pentru a forma un ciclu elementar. Numărul de
moduri în care putem alege 4 noduri din cele 6 disponibile este dat de combinația C64
Odată ce am ales cele 4 noduri, trebuie să formăm 4 muchii. Deși putem alege oricare 4 muchii posibile, unele dintre
ele sunt identice din punct de vedere al ciclurilor elementare. De exemplu, dacă avem 4 noduri consecutive a, b, c, d,
vom avea două moduri de alege două muchii pentru a forma un ciclu elementar: (a, b), (c, d) sau (a, d), (b, c). Aceste
două cicluri sunt identice prin rotație, deoarece putem roti muchiile în jurul nodurilor și vom ajunge la aceeași structură.
Prin urmare, trebuie să eliminăm ciclurile identice prin rotație. Avem două muchii în plus față de cele necesare pentru
a forma un ciclu, iar acestea pot fi aranjate în două moduri distincte:
(1) una dintre ele împarte ciclul în două părți egale, iar cealaltă completează ciclul în jurul nodurilor rămase;
(2) cele două muchii pot fi alese astfel încât să fie în partea de sus și în partea de jos a ciclului.
Pentru a alege cele două muchii, avem C42 posibilități. Cum două dintre aceste posibilități sunt cicluri identice prin
rotație, împărțim numărul total de cicluri elementare cu 2.
În final, numărul total de cicluri elementare distincte cu 4 muchii este dat de produsul C6^4 * C4^2 / 2 = 45.

7. Se dă tabloul unidimensional (0, 1, 3, 4, 6, 7, 8, 9, 12, 13, 15, 17, 19, 21, 23). Folosind metoda căutării binare se verifică
dacă în tablou există elementul cu valoarea x. Valoarea x este comparată cu trei elemente ale tabloului pe parcursul
aplicării metodei, până când este găsită ca prezentă. Cu care dintre valorile de mai jos x poate să fie egal? (9 pct.)
a) 6; b) 19; c) 8; d) 23; e) 15; f) 13.
Rezolvare:

Problema cere ca să găsim un număr x din doar 3 aplicări ale metodei de Căutare Binară.
Metoda presupune căutarea unui element specific într-un array sortat. Ideea principală este să se compare elementul
căutat cu elementul de mijloc al array-ului, eliminând astfel o jumătate din array:
• Dacă elementul căutat este mai mare decât elementul din mijloc, căutarea va continua în partea din dreapta a array-
ului;
• Dacă este mai mic, căutarea va continua în partea din stânga a array-ului.
Acest proces se repetă până când elementul este găsit sau până când se ajunge la sfârșitul array-ului și se constată că
elementul căutat nu există în array. Metoda Căutării Binare are o complexitate a timpului logaritmică O(log n), unde n
reprezintă dimensiunea array-ului. Analizând cazurile pe rând vom avea:
a) Se ia mijlocul array-ului: 9. Cum 6 < 9 căutăm în partea stângă, astfel făcând prima comparare.
Căutăm mijlocul: 4. Cum 6 > 4 căutăm în partea dreaptă, astfel făcând a doua comparare.
Căutăm mijlocul: 7. Cum 6 > 7 se face a treia comparare și numărul nu este găsit.
b) 19 > 9; 19 > 17; 19 < 21
c) 8 < 9; 8 > 4; 8 > 7
d) 23 > 9; 23 > 17; 23 > 21;
e) 15 > 9; 15 < 17; 15 > 13
f) 13 > 9; 13 < 17; 13 = 13, găsindu-se astfel din doar 3 comparări.
8. Specificați ce afișează următoarea secvență de cod: (9 pct.)
Varianta C/C++ Varianta Pascal
char c[12]="PREAdmitere"; var
int i, j; c: array[0..10] of char = 'PREAdmitere';
for(i=0; i<strlen(c); i++) p: PChar;
{ i,j: Integer;
if(i == 3) begin
c[i] = 'r'; for i := 0 to Length(c) - 1 do begin
for(j=0; j<strlen(c)&&c[j]!='r'; j++); if i = 3 then c[i] := 'r';
printf("%d", j); for j := 0 to Length(c) - 1 do begin
/* cout<<j; // versiunea C++ */ if c[j] = 'r' then break;
} end;
write(j);
end;
end.

a) 33333333999; b) 9333333333; c) 99999999999; d) 3333333999; e) 33333333333; f) 99933333333


Rezolvare:

Acest algoritm utilizează un șir de caractere inițializat cu valoarea "PREAdmitere" și parcurge fiecare caracter din șir.
La poziția 4 din șir (adică la litera "A"), valoarea caracterului este schimbată în "r", astfel șirul devenind "PRErdmitere".
În interiorul primului ciclu "for", se pornește un al doilea ciclu "for" care parcurge șirul de la început și se oprește când
întâlnește prima apariție a caracterului "r". Prin urmare, în primele patru iterații ale primului ciclu "for", se va afișa
poziția caracterului "r" înainte de a fi modificat, iar pentru restul iterațiilor se va afișa poziția caracterului "r", după
modificare.
Astfel, pentru primele patru iterații se va afișa 9, care este poziția primei apariții a caracterului "r" în șirul inițial
"PREAdmitere". Pentru următoarele opt iterații se va afișa 3, care este poziția primei apariții a caracterului "r" în șirul
modificat "PRErdmitere".
Prin urmare, răspunsul corect la întrebare este f).

9. Se consideră funcția recursivă următoare, unde literalii x și y sunt două numere naturale:
Varianta C/C++ Varianta Pascal
int f(int a, int b) function f(a: integer; b: integer): integer;
{ begin
if(a == b) if (a = b) then f := 0
return 0; else
if(b % a == 0) if (b mod a = 0) then f := a + b
return a + b; else
return f(a + x, b - y); f := f(a + x, b - y);
} end;

Care sunt numerele naturale x și y din intervalul [1,25], astfel încât rezultatul apelului f(1000,2004) să fie 0, iar numărul
de apeluri recursive să fie maxim 300. (9 pct.)
a) (x=16,y=20); (x=17,y=21); (x=18,y=22); b) (x=1,y=1); (x=2,y=2); (x=3,y=1);
c) (x=1,y=3); (x=20,y=24); (x=21,y=25); d) (x=13,y=17); (x=14,y=18); (x=15,y=19);
e) (x=1,y=3); (x=2,y=2); (x=3,y=1); f) (x=6,y=10); (x=7,y=11); (x=9,y=13).
Rezolvare:
Pentru a găsi perechile (x, y) care duc la f(1000,2004) = 0 și numărul maxim de apeluri recursive de 300, putem utiliza
următorul algoritm:
• Parcurgem toate perechile de numere (x, y) din intervalul [1, 25];
• Pentru fiecare pereche (x, y), apelăm funcția f(1000, 2004, 0, x, y) și verificăm dacă aceasta returnează 0 și numărul
de apeluri recursive este maxim 300;
• Dacă găsim o astfel de pereche, o salvăm și continuăm căutarea;
• La final, afișăm toate perechile găsite.
Codul pentru implementarea acestui algoritm în C/C++ ar putea arăta astfel:

#include <iostream>

using namespace std;

int f(int a, int b, int count, int x, int y) {


if(a == b)
return 0;
if(b % a == 0)
return a + b;
if(count >= 300) // verificam sa nu avem mai mult de 300 de apeluri recursive
return count;
return f(a + x, b - y, count+1, x, y);
}

int main() {
for(int x=1; x<=25; x++) {
for(int y=1; y<=25; y++) {
int count = f(1000, 2004, 0, x, y);
if(count == 0) {
cout << "(" << x << "," << y << ")" << endl;
}
}
}
return 0;
}

Astfel, rulându-se fiecare variantă de răspuns, găsim ca se verifica doar pentru


e) (x=1,y=3); (x=2,y=2); (x=3,y=1);
10. Se citesc numerele naturale nenule 𝑛, 𝑎, 𝑚1 , 𝑚2 , 𝑚3. Un program generează mulțimea M astfel: a) 𝑎 ∈ 𝑀 b) dacă 𝑥 ∈
𝑀 atunci 𝑚1 ∗ 𝑥 ∈ 𝑀 și 𝑚2 ∗ 𝑥 ∈ 𝑀 și 𝑚3 ∗ 𝑥 ∈ 𝑀. Mulțimea M este ordonată după relația „<”. Programul afișează
al 𝑛-lea element din mulțime. Ce se afișează pentru execuția programului cu datele de intrare 8 1 2 3 4? (9 pct.)
a) 9; b) 16; c) 10; d) 8; e) 12; f) 14.
Rezolvare:
Pentru a genera mulțimea M, începem cu elementul a și aplicăm regulile programului pentru a obține noi elemente și
continuăm până când avem un număr suficient de elemente pentru a afla al n-lea element.
În cazul datelor de intrare 8 1 2 3 4, mulțimea M arată astfel:
M = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 32, 36, 48, 64, 72, 96, 128, 144, 192, 256, 288, 384, 512}
Ordonarea elementelor este 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 32, 36, 48, 64, 72, 96, 128, 144, 192, 256, 288, 384, 512.
Al 8-lea element din această mulțime este 12, deci răspunsul este 12.

S-ar putea să vă placă și