www.agora.ro

Al doilea bacalaureat în informatică

BACALAUREAT 2000

Continuă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 1

1. 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 2

1. 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:

Listing CONVERSIE.PAS

Varianta C:

Listing CONVERSIE.CPP

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:

Listing CUVINTE.PAS

Varianta C:

Listing CUVINTE.CPP

Subiectul 3

Se 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:

Listing _0_1.PAS

Varianta C:

Listing _0_1.CPP

Subiectul 4

1. 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:

Listing BAC.PAS

Varianta C:

Listing BAC.CPP

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]