Salut! Acum ajungem la nivelul cel mai avansat: programe complete pentru Bacalaureat. Aceste probleme valorează 10 puncte fiecare și testează toate competențele tale. Hai să le abordăm sistematic!
🎯 Strategia pentru Probleme de Programare Completă
- Citește cerința 3 ori – Înțelege exact ce se cere
- Analizează exemplul – Exemplele sunt cheia pentru înțelegere
- Împarte în subprobleme – Rezolvă bucată cu bucată
- Scrie pseudocod – Pe hârtie, în română
- Implementează – Tradu în C/C++
- Testează – Cu datele din exemplu
📚 Rezolvări Complete pentru Fiecare Problemă
Problema 1: Eliminarea Diagonalei Secundare și Shiftare
Cerința: Elimină elementele de pe diagonala secundară și mută celelalte spre stânga.
Exemplu pentru n=4:
Initial: Dupa eliminare:
1 2 3 4 X X X X
5 6 7 8 5 6 7 X
9 10 11 12 9 10 X 12
13 14 15 16 13 X 15 16
Dupa shiftare:
1 2 3 4 X X X X
5 6 7 X 5 6 7 X
9 10 X 12 9 10 12 X
13 X 15 16 13 15 16 X
Soluție:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101];
// Citire
cin >> n;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
// Pas 1: Marcam elementele de pe diagonala secundara cu -1
for(int i = 0; i < n; i++) {
a[i][n-1-i] = -1; // -1 = pozitie libera
}
// Pas 2: Shiftare spre stanga pentru fiecare linie
for(int i = 0; i < n; i++) {
// Parcurgem de la stanga la dreapta si mutam elemente peste -1
for(int j = 0; j < n-1; j++) {
if(a[i][j] == -1) {
// Mutam urmatorul element in locul acesta
a[i][j] = a[i][j+1];
a[i][j+1] = -1;
}
}
}
// Pas 3: Afisare (inlocuim -1 cu 0 sau lasam spatiu)
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(a[i][j] == -1) cout << " ";
else cout << a[i][j];
if(j < n-1) cout << " ";
}
cout << endl;
}
return 0;
}
Varianta mai simplă cu tabloul auxiliar:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], b[101][101] = {0};
cin >> n;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
// Construim noul tablou
for(int i = 0; i < n; i++) {
int col = 0;
for(int j = 0; j < n; j++) {
// Daca NU e pe diagonala secundara, il punem
if(j != n-1-i) {
b[i][col] = a[i][j];
col++;
}
}
// Restul pozitiilor raman 0
}
// Afisare
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
cout << b[i][j] << " ";
}
cout << endl;
}
return 0;
}
Problema 2: Înlocuirea Coloanei cu Numărul Minim
Cerința: Găsește coloana cu elementul minim și înlocuiește toate elementele ei cu elementul din dreapta-jos.
Exemplu:
Initial:
17 10 11
12 16 21
5 2 8
19 4 9
Minim = 2 (pe linia 2, coloana 1)
Elementul dreapta-jos = 9
Dupa inlocuire:
17 10 11
12 16 21
9 9 9 <- toata coloana 1 devine 9
19 4 9
Soluție:
#include <iostream>
using namespace std;
int main() {
int m, n, a[101][101];
cin >> m >> n;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
// 1. Gasim minimul si coloana lui
int minim = a[0][0];
int coloanaMinim = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(a[i][j] < minim) {
minim = a[i][j];
coloanaMinim = j;
}
}
}
// 2. Elementul din dreapta-jos
int dreaptaJos = a[m-1][n-1];
// 3. Inlocuim toata coloana
for(int i = 0; i < m; i++) {
a[i][coloanaMinim] = dreaptaJos;
}
// 4. Afisare
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
Problema 3: Transformarea Textului cu Cratime
Cerința: Transformă spații multiple între cuvinte în ” – “.
Exemplu: "anul acesta devin student" → "anul - acesta - devin - student"
Soluție:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char text[101], rezultat[201] = "";
cin.getline(text, 101);
int i = 0, j = 0;
int inCuvant = 0; // 0 = in spatiu, 1 = in cuvant
while(text[i] != '\0') {
if(text[i] != ' ') {
// Suntem intr-un cuvant
if(inCuvant == 0 && j > 0) {
// S-a terminat spatiul dintre cuvinte
rezultat[j++] = ' ';
rezultat[j++] = '-';
rezultat[j++] = ' ';
}
rezultat[j++] = text[i];
inCuvant = 1;
} else {
// Suntem in spatiu
inCuvant = 0;
}
i++;
}
rezultat[j] = '\0';
cout << rezultat;
return 0;
}
Varianta cu strtok (mai simplă):
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char text[101], cuvant[101];
char *p;
char rezultat[201] = "";
int primulCuvant = 1;
cin.getline(text, 101);
p = strtok(text, " ");
while(p != NULL) {
if(!primulCuvant) {
strcat(rezultat, " - ");
}
strcat(rezultat, p);
primulCuvant = 0;
p = strtok(NULL, " ");
}
cout << rezultat;
return 0;
}
Problema 4: Grădina cu Flori și Gazon
Cerința: Parcelele cu flori trebuie să fie cu cel puțin 1 decimetru mai înalte decât gazonul de pe rândul anterior. Gazonul prea înalt se taie.
Analiză exemplu:
Initial (m=4, n=6):
Linia 1 (gazon): 6 7 8 8 7 6
Linia 2 (flori): 2 3 5 7 2 5
Linia 3 (gazon): 7 9 9 6 5 9
Linia 4 (flori): 4 8 2 9 3 8
Regula: Florile de pe linia i trebuie sa fie > gazonul de pe linia i-1 cu cel putin 1
Dar florile nu se modifica, doar gazonul se taie!
Soluție:
#include <iostream>
using namespace std;
int main() {
int m, n, a[101][101];
cin >> m >> n;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
// Parcurgem liniile cu gazon (liniile impare: 0, 2, 4... index 0-based)
for(int i = 0; i < m; i += 2) { // i = linia cu gazon
// Daca exista o linie cu flori dupa (i+1 < m)
if(i + 1 < m) {
for(int j = 0; j < n; j++) {
// Daca gazonul este prea inalt fata de florile de sub el
// Florile trebuie sa fie > gazon cu cel putin 1
// Deci gazonul trebuie sa fie <= flori - 1
if(a[i][j] >= a[i+1][j]) {
a[i][j] = a[i+1][j] - 1;
if(a[i][j] < 2) a[i][j] = 2; // limita inferioara
}
}
}
}
// Parcurgem liniile cu gazon (cele pare: 1, 3, 5... index 0-based)
for(int i = 1; i < m; i += 2) { // i = linia cu gazon
// Daca exista o linie cu flori inainte (i-1 >= 0)
for(int j = 0; j < n; j++) {
// Gazonul de pe linia i trebuie verificat cu florile de pe linia i-1
if(a[i][j] >= a[i-1][j]) {
a[i][j] = a[i-1][j] - 1;
if(a[i][j] < 2) a[i][j] = 2;
}
}
}
// Afisare
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
Problema 5: Pătrat de Valoare Maximă (2×2)
Cerința: Găsește submatricea 2×2 cu suma maximă.
Soluție:
#include <iostream>
using namespace std;
int main() {
int m, n, a[21][21];
cin >> m >> n;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
int maxSum = -1;
// Parcurgem toate submatricele 2x2
for(int i = 0; i < m-1; i++) {
for(int j = 0; j < n-1; j++) {
int suma = a[i][j] + a[i][j+1] + a[i+1][j] + a[i+1][j+1];
if(suma > maxSum) {
maxSum = suma;
}
}
}
cout << maxSum;
return 0;
}
Problema 6: Vocală Prietenă pentru Consoane
Cerința: Fiecare consoană se înlocuiește cu vocala care o precede fără alte vocale între ele.
Analiză:
- Alfabet: a b c d e f g h i j k l m n o p q r s t u v w x y z
- Vocale: a, e, i, o, u
- Pentru ‘m’: vocalele care îl preced: i (are ‘j’, ‘k’, ‘l’ între), o (nu, are doar consoane)
- Regula: Ultima vocală înainte de consoană, fără alte vocale între
Soluție simplificată: Pentru fiecare consoană, o înlocuim cu vocala anterioară:
- b → a, c → a, d → a, f → e, g → e, h → e, j → i, k → i, l → i, m → i, n → i, p → o, q → o, r → o, s → o, t → o, v → u, w → u, x → u, y → u, z → u
Soluție:
#include <iostream>
#include <cstring>
using namespace std;
int esteVocala(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
char vocalaPrietenie(char consoana) {
// Pentru fiecare consoana, returnam vocala corespunzatoare
if(consoana >= 'b' && consoana <= 'd') return 'a';
if(consoana >= 'f' && consoana <= 'h') return 'e';
if(consoana >= 'j' && consoana <= 'n') return 'i';
if(consoana >= 'p' && consoana <= 't') return 'o';
if(consoana >= 'v' && consoana <= 'z') return 'u';
return consoana; // daca nu e consoana
}
int main() {
char parola[51], codificata[51];
cin >> parola;
for(int i = 0; parola[i] != '\0'; i++) {
if(esteVocala(parola[i])) {
codificata[i] = parola[i]; // vocalele raman asa
} else {
codificata[i] = vocalaPrietenie(parola[i]);
}
}
codificata[strlen(parola)] = '\0';
cout << codificata;
return 0;
}
Problema 7: Cuvinte Asemenea
Cerința: Găsește toate cuvintele cu același număr de vocale ca ultimul cuvânt.
Soluție:
#include <iostream>
#include <cstring>
using namespace std;
int numarVocale(char cuvant[]) {
int count = 0;
for(int i = 0; cuvant[i] != '\0'; i++) {
char c = cuvant[i];
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
count++;
}
return count;
}
int main() {
int n;
char cuvinte[11][21]; // maxim 10 cuvinte a cate 20 caractere
cin >> n;
for(int i = 0; i < n; i++) {
cin >> cuvinte[i];
}
int vocaleUltim = numarVocale(cuvinte[n-1]);
int exista = 0;
// Parcurgem toate cuvintele in afara de ultimul
for(int i = 0; i < n-1; i++) {
if(strcmp(cuvinte[i], cuvinte[n-1]) != 0) { // distincte
if(numarVocale(cuvinte[i]) == vocaleUltim) {
if(exista) cout << " ";
cout << cuvinte[i];
exista = 1;
}
}
}
if(!exista) {
cout << "nu exista";
}
return 0;
}
🎯 Sfaturi pentru Probleme Complexe
- Citește cu atenție – Subliniază condițiile importante
- Folosește exemplele – Sunt cele mai bune ghiduri
- Împarte problema – Rezolvă bucată cu bucată
- Testează incremental – După fiecare pas, testează
- Gestionează memoria – Folosește dimensiuni suficiente
- Verifică cazurile limită – n=1, m=1, sir vid, etc.
💪 Exercițiu de Practică
Încearcă să rezolvi singur următoarea problemă:
Cerință: Scrie un program care citește n numere și afișează cele care au suma cifrelor egală cu produsul cifrelor.
Soluție:
#include <iostream>
using namespace std;
int main() {
int n, numar;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> numar;
int suma = 0, produs = 1, temp = numar;
while(temp > 0) {
int cifra = temp % 10;
suma += cifra;
produs *= cifra;
temp /= 10;
}
if(suma == produs) {
cout << numar << " ";
}
}
return 0;
}
✨ Motivare Finală
Uite ce uimitor! Acum poți să rezolvi aproape orice problemă de la Bacalaureat. Ai parcurs o cale lungă: de la bazele gândirii algoritmice până la programe complexe.
Cel mai important lucru pe care l-ai învățat: Orice problemă complexă este doar o colecție de probleme simple puse împreună.
La examen:
- Răspunde la ce știi – Nu lăsa nimic necompletat
- Gestionează-ți timpul – Alocă timp proporțional cu punctajul
- Ai încredere în tine – Ai practicat suficient!
Succes la Bacalaureat! Tu poți să iei nota maximă! 🚀🎯
Leave a Reply