Al doilea bacalaureat în informatică BACALAUREAT 2000Continuăm prezentarea soluțiilor subiectelor de Bacalaureat propuse spre rezolvare în cartea Bac Info' 2000; în acest număr veți găsi varianta nr. 18.
Subiectul 11. Scrieți o secvență de instrucțiuni în pseudocod, care să aibă ca efect determinarea numărului cifrelor numărului natural n.
Soluție Deoarece numărul poate fi și 0, algoritmul trebuie să afișeze 1 în acest caz. Altfel, acesta se împarte la 10 cât timp este diferit de 0. La fiecare împărțire, contorul crește cu 1. citește n dacă n=0 atunci scrie '1' altfel nr_cifre Ź 0 cât timp n > 0 execută n Ź [n/10] nr_cifre Ź nr_cifre+1
sfârșit cât timp scrie nr_cifre
sfârșit dacă 2. Care dintre următoarele afirmații sunt adevărate și care sunt false? a) Orice algoritm poate fi scris, folosind doar structuri secvențiale, alternative de tip if-then-else și structuri repetitive anterior condiționate. b) Într-un program structurat nu se va folosi instrucțiunea goto. c) Utilizarea instrucțiunii case în (Pascal), respectiv switch (în C) contravine principiilor programării structurate. d) Conform principiilor programării structurate nu se vor efectua salturi forțate din interiorul unei structuri repetitive. e) În cazul folosirii instrucțiunii goto, în program trebuie să existe în mod obligatoriu o instrucțiune etichetată cu eticheta din goto. Justificați răspunsurile.
Soluție a) Afirmația este adevărată, deoarece exprimă exact teorema lui Böhm și Jacopini. b) Afirmația este adevărată, deoarece principiile programării structurate interzic folosire instrucțiunii goto în programe. c) Afirmația este falsă, deoarece utilizarea celor două instrucțiuni (case în Pascal, respectiv switch în C) nu contravine principiilor programării structurate. Aceste instrucțiuni sunt similare cu instrucțiunea if, dar realizează o ramificare multiplă. d) Afirmația este adevărată; conform principiilor programării structurate nu se vor efectua salturi forțate din interiorul unei structuri repetitive. e) Afirmația este adevărată, deoarece folosirea instrucțiunii goto înseamnă solicitarea continuării execuției unui program nu cu instrucțiunea imediat următoare, ci cu o instrucțiune aflată oriunde în blocul respectiv, care trebuie să fie identificabilă. Identificarea ei se realizează prin intermediul etichetei. 3. Care este efectul următorului subprogram? Varianta Pascal: procedure oare_ce_e(var _text:string; n,k:Byte); var i,j:Byte; aux:Char; begin for j:=1 to k do
begin aux:=_text[1]; for i:=2 to n do _text[i-1]:=_text[i]; _text[n]:=aux end
end;
Varianta C: void oare_ce_e(char* _text,int n,int k){ char aux; for (int j=0;j<k;j++){ aux=_text[0]; for (int i=1;i<n;i++) _text[i-1]=_text[i]; _text[n-1]=aux; } }
Soluție Procedura (funcția) oare_ce_e realizează o permutare circulară a șirului de caractere _text cu k poziții. 4. Ce se va afișa pe ecran în urma execuției programului:
Varianta Pascal: Program Nu_e_ghicitoare; var x,y,u,v:Byte;
Begin Readln(x,y); u:=x; v:=y; while x<>y do if x>y then begin x:=x-y; u:=u+v end else begin y:=y-x; v:=v+u end; Writeln(x,' ',(u+v) div 2) End.
Varianta C: #include <stdio.h> void main(void){ int x,y,u,v; scanf("%d%d",&x,&y); while(x!=y) if(x>y)x-=y,u+=v; else y-=x,v+=u; printf("%d %d",x,(u+v)/2); }
Soluție Programul calculează (fără să efectueze nici o înmulțire și doar o împărțire la 2) cel mai mare divizor comun, respectiv cel mai mic multiplu comun a două numere x și y.
Subiectul 21. Scrieți un program comentat care convertește un număr dat în baza p în baza q și afișează această reprezentare (p,qŁ10).
Soluție Vom converti în baza 10 numărul dat (dacă acesta nu este dat în baza 10) și apoi numărul obținut îl vom vconverti în baza q (dacă nu trebuie convertit în baza 10). Dacă p=q atunci nu are rost să convertim numărul.
Varianta Pascal:
Varianta C: 2. Scrieți un program recursiv care citește n cuvinte de la tastatură și le afișează în ordinea inversă citirii. (Cuvintele nu vor fi memorate într-un tablou.)
Soluție Varianta Pascal:
Varianta C: Subiectul 3Se citește de la tastatură un număr natural nenul nŁ8. Să se genereze, folosind metoda backtracking, toate șirurile de lungime n, formate din cifre de 0 și 1. Programul va fi comentat. Exemplu: pentru n=2 se va afișa: 0 0 0 1 1 0 1 1
Soluție Varianta Pascal:
Varianta C:
Subiectul 41. Un fișier text al cărui nume se introduce de la tastatură cuprinde numele și media de la examenul de bacalaureat a unor absolvenți. Scrieți programul comentat care calculează media generală a absolvenților din fișier și scrie această medie într-un alt fișier.
Soluție Varianta Pascal: Varianta C:
2. Scrieți două subprograme care realizează inserarea, respectiv eliminarea unui element într-o coadă. Coada a fost definită astfel:
Varianta Pascal: type coada=^data; data= record an:1900..2000; luna:1..12; zi:1..31; urm:coada end;
Varianta C: struct coada{ int an,luna,zi; coada* urm; }; Subprogramul va avea doi parametri de tip coada care indică primul, respectiv ultimul element existent în coadă.
Soluție Pentru simplificare considerăm că am folosit o implementare cu santinelă a cozii. Inserarea în coadă se realizează după ultimul element, iar eliminarea din coadă înseamnă ștergerea elementului care urmează după santinelă, deci, de fapt, primul element "real" al cozii. Evident, înainte de a elimina un element va trebui să verificăm dacă există cel puțin un element în coadă. De obicei se dorește să fie eliberat spațiul alocat elementului care se elimină. Presupunând că cei doi pointeri definiți și inițializați, către primul (santinela), respectiv, ultimul element din coadă sunt primul și ultimul, inserarea și eliminarea se realizează cu următoarele subprograme:
Varianta Pascal: procedure inserare(var ultimul:coada); var p:coada; begin New(p); Readln(p^.an,p^.luna,p^.zi); p^.urm:=nil ultimul^.urm:=p; ultimul:=p end;
procedure eliminare(var primul:coada); var p:coada; begin if primul^.urm = nil then Writeln('Coada este vida!') else begin p:=primul^.urm; primul^.urm:=primul^.urm^.urm; Dispose(p) end end;
Varianta C: void inserare(coada* &ultimul){ coada *p=new coada; fscanf("%d%d%d",p->an,p->luna,p->zi); p->urm=NULL; ultimul->urm=p; ultimul=p; }
void eliminare(coada* &primul){ coada *p=new coada; if (!primul->urm) puts("Coada este vida!"); else{ p=primul->urm; primul->urm=primul->urm->urm; delete p; } }
Subiectul 1: 30 puncte 1) 7,5 puncte 2) 7,5 puncte 3) 7,5 puncte 4) 7,5 puncte Subiectul 2: 20 puncte 1) 10 puncte 2) 10 puncte Subiectul 3: 20 puncte Subiectul 4: 20 puncte 1)10 puncte 2) 10 puncte Se acordă 10 puncte din oficiu. TOTAL: 100 puncte [cuprins] |