Documente Academic
Documente Profesional
Documente Cultură
1
11212 115 1222
11221 121111 1231
1123 12112 124
11311 12121 ......
1132 1213
1141 12211
#include<fstream.h>
#include<math.h>
ofstream f("suma.txt");
int x[50],k,valid,n,m,nr;
void citire()
{
cout<<"n=";cin>>n;
}
void posibil(int k,int &valid)
{ /*x[k] poate fi adaugata in vectorul solutie daca prin adaugarea ei nu suma elementelor din vectorul
solutie nu depaseste n*/
valid=1;
int s=0;
for(int i=1;i<=k;i++) s=s+x[i];
if(s>n) valid=0;
}
int solutie(int k) /*avem solutie daca suma elementelor din vectorul solutie este egala cu n*/
{int s=0;
for(int i=1;i<=k;i++) s=s+x[i];
if(s==n) return 1;
else return 0;
}
void afisare(int k) /*afisam elementele din vectorul solutie*/
{nr++;
2
Exemplu:
1 1 4 2 1 3 3 2 1
1 2 3 2 2 2
1 3 2 2 3 1
1 4 1 3 1 2
411
x[k]=0; }
while(k>0) if(!valid)k--;
{ else if(solutie(k)) afisare(k);
valid=0; else {
while(!valid && x[k]<n) k++;
{ x[k]=0;
x[k]=x[k]+1; }
posibil(k,valid); }
3
} back();
void main() f.close();
{ }
citire();
nr=0;
4
3. Sa se scrie un numar n ca suma de numere prime.
Exemplu:
2 2 2 2 2 3 2 5
2 2 3 3 3 3 2 2
2 3 2 3 3 5 2
2 3 3 2 3 7
2 3 5 5 2 3
2 5 3 5 3 2
3 2 2 3 5 5
3 2 3 2 73
5
}
1111111 1132
111112 1141
111121 115
11113 121111
111211 12112
11122 12121
11131 1213
1114 12211
112111 1222
11212 1231
11221 124
1123 ......
11311
#include<fstream.h>
#include<math.h>
ofstream f("suma.txt");
int x[50],k,valid,n,m,nr;
void citire()
{
cout<<"n=";cin>>n;
}
void posibil(int k,int &valid)
{ /*x[k] poate fi adaugata in vectorul solutie daca prin adaugarea ei nu suma elementelor din
6
void back()
vectorul solutie nu depaseste n*/ else {
{valid=1; k++;
int s=0;
k=1; x[k]=0;
for(int i=1;i<=k;i++) s=s+x[i];
x[k]=0; }
if(s>n) valid=0;
while(k>0) }
{} }
int valid=0;
solutie(int k) /*avem solutie daca suma elementelor dinvoid vectorul
main()
solutie este egala cu n*/
{intwhile(!valid
s=0; && x[k]<n) {
for(int
{ i=1;i<=k;i++) s=s+x[i]; citire();
if(s==n)
x[k]=x[k]+1;
return 1; nr=0;
posibil(k,valid);
else return 0; back();
} }
f.close();
void
if(!valid)k--;
afisare(int k) /*afisam elementele din vectorul solutie*/
}
{nr++;else if(solutie(k)) afisare(k);
for(int i=1;i<=k;i++)f<<x[i]<<" ";
5. Sa f<<endl;
se afiseze un numar n ca suma de m numere naturale.
Exemplu: }
pentru n=6 si m=3 se afiseaza:
1 1 4 2 1 3 3 2 1
1 2 3 2 2 2 411
1 3 2 2 3 1
1 4 1 3 1 2
X[k] poate fi adaugat la solutie daca suma elementelor din vectorul solutie nu depaseste n.
Avem solutie daca suma elementelor din vecotorul solutie este n si numarul de elemente din solutie este
m.
#include<fstream.h>
#include<math.h>
ofstream f("suma1.txt");
int x[50],k,valid,n,m,nr;
void citire()
{/*citim datele de intrare*/
cout<<"n=";cin>>n;
cout<<"m=";cin>>m;
}
void posibil(int k,int &valid)
{ /*x[k] poate face parte din vectorul solutie daca prin adaugarea lui suma elementelor din vector nu
depaseste n*/
valid=1;
int s=0;
for(int i=1;i<=k;i++) s=s+x[i];
if(s>n) valid=0;
}
int solutie(int k)
{int s=0; /*avem solutie daca suma elementelor din vectorul solutie este n si numaul de elemente din
vectorul solutie este m*/
for(int i=1;i<=k;i++) s=s+x[i];
if(s==n&&k==m) return 1;
else return 0;
7
}
8
if(prim(x[k])==0) valid=0;
int s=0;
for(i=1;i<=k;i++) s=s+x[i];
if(s>n) valid=0;
}
int solutie(int k) /*avem solutie daca suma elementelor din vectorul solutie este egala cu n*/
{int s=0;
for(int i=1;i<=k;i++) s=s+x[i];
if(s==n) return 1;
else return 0;
}
void afisare(int k)/*afisam solutia gasita*/
{nr++;
for(int i=1;i<=k;i++)f<<x[i]<<" ";
f<<endl;
}
9
1 - galben
2 - portocaliu
3 - rosu
4 - visiniu
5 - verde
6 - albastru.
- daca k=2 (se completeaza culoarea din mijloc) aceasta trebuie sa fie diferita de galben sau visiniu.
#include<fstream.h>
#include<math.h>
ofstream f("steag.txt");
int x[50],k,valid;
valid=1;
{ f<<endl;
for(int i=1;i<=k;i++) }
10
void back() if(!valid)k--;
{ }
valid=0; }
{ {
} }
9. Se citeste de la tastatura un cuvant. Sa se afiseze toate anagramarile cuvantului.
Pentru backtracking trebuie sa folosim elemente consecutive, prin urmare vom folosii indicii elementelor
din vector si vom codifica elementele cu acesti indici.
Prin urmare, x[k] reprezinta elementul aflat pe poztia x[k] in sir si in acelasi timp, elementul aflat pe pozitia
k in vectorul solutie.
Problema se rezuma la problema de generare a permutarilor diferenta fiind doar la afisare cand afisam
elementele din sir aflate pe pozitiile x[i], i=1..n.
Exemplu:
s="abcd".
Se va afisa:
Avem in vedere ca elementele din sir ocupa pozitiile 0...n-1 unde n este lungimea sirului.
Atunci cand lucram cu siruri trebuie sa introducem biblioteca string.h.
Datorita faptului ca primul element din sir se gaseste pe pozitia 0 inseamna ca elementul minim are
valoarea 0. Elementul maxim este n-1 deoarece in sirul de caractere ultima pozitie ocupata este n-1.
Observatie: A nu se face confuzie intre vectorul solutie si sirul de caractere.
11
#include<fstream.h>
#include<string.h>
ofstream f("cuvant.txt");
int x[50],k,valid,n;
char s[50];
void citire() /*citim datele de intrare*/
{cout<<"sir=";cin>>s;
}
void posibil(int k,int &valid) /*elementele nu se repeta*/
{
valid=1;
for(int i=1;i<=k-1;i++) if (x[k]==x[i]) valid=0;
}
int solutie(int k) /*avem solutie cand cuvantul anagramat are un numar de caractere ca si cuvantul de
baza*/
{
if(k==n) return 1;
else return 0;
}
12
#include<fstream.h>
#include<string.h>
ofstream f("muzica.txt");
int x[50],k,valid,n;
void citire()
{cout<<"n=";cin>>n;
}
void posibil(int k,int &valid)
{
valid=1;
for(int i=1;i<=k-1;i++) if (x[k]==x[i]) valid=0; /*melodiile nu se repeta*/
if(x[k]==1) for(i=1;i<=k-1;i++) if(x[i]==2) valid=0;/*melodia 2 nu poate sa apara inainte melodii 1*/
}
int solutie(int k)
{ /*avem solutia cand se inscriptioneaza toate cele n melodii*/
if(k==n) return 1;
else return 0;
}
void afisare(int k)
{ /*afisam solutia*/
for(int i=1;i<=k;i++)
f<<x[i];
f<<endl;
}
void back()
{
k=1;
x[k]=0;
while(k>0)
{
valid=0;
while(!valid && x[k]<n)
{
x[k]=x[k]+1;
posibil(k,valid);
}
if(!valid)k--;
else if(solutie(k)) afisare(k);
else {
k++;
x[k]=0;
}
}
}
void main()
{
citire();
back();
f.close();
}
11. Dintr-o cusca trebuie scosi n lei si m tigrii. Sa se afiseze toate posibilitatile de a scoate din cusca
animalele astfel incat sa nu iasa 2 tigrii unul dupa altul (numarul de tigrii<=numarul de lei).
Exemplu:
leu leu leu tigru leu tigru leu tigru leu leu leu tigru
leu leu tigru leu leu tigru leu tigru leu leu tigru leu
leu leu tigru leu tigru leu leu tigru leu tigru leu leu
13
tigru leu leu leu leu tigru tigru leu leu tigru leu leu
tigru leu leu leu tigru leu tigru leu tigru leu leu leu
O sa codificam leii cu 0 si tigrii cu 1. Aceasta codificare nu e unica, fiecare programator poate sa-si faca
propria-i codificare.
Obsevam ca valoarea minima este 0 si valoarea maxima este 1.
Avem solutie cand am scos din cusca toti leii si toti tigrii.
In functia posbil vom elimina solutiile in care 2 tigrii pot iesii unul dupa altul. Din cusca nu pot iesi mai
multi tigrii sau lei decat exista.
#include<fstream.h>
#include<stdlib.h>
ofstream f("leitig.txt");
int x[50],k,valid,n,m;
void citire() /*citim datele de intrare*/
{cout<<"n=";cin>>n;
cout<<"m=";cin>>m;
if(m>n) {cout<<"imposibil";exit(0);}
}
void posibil(int k,int &valid)
{
valid=1;
/*numaram leii si tigrii din solutie*/
int lei=0;
int tig=0;
for (int i=1;i<=k;i++)
if(x[i]==0)lei++;
else tig++;
if(lei>n||tig>m)valid=0; /*nu putem scoate din cusca mai mult de n lei sau mai mult de m tigrii*/
if(x[k]==1&&x[k-1]==1) valid=0; /*nu putem scoate din cusca 2 tigrii unul dupa altul*/
}
int solutie(int k)
{ /*avem solutie daca am scos din cusca n lei si m tigrii*/
int lei=0;
int tig=0;
for (int i=1;i<=k;i++)
if(x[i]==0)lei++;
else tig++;
if(lei==n&&tig==m)return 1;
else return 0;
}
void afisare(int k)
{/*Afisam solutia*/
for(int i=1;i<=k;i++)
if(x[i]==0) f<<"leu ";
else f<<"tigru ";
f<<endl;
}
void back()
{
k=1;
x[k]=-1;/*initializam x[k] cu valoarea minima - 1*/
while(k>0)
{
valid=0;
while(!valid && x[k]<1)
{
x[k]=x[k]+1;
14
posibil(k,valid);
}
if(!valid)k--;
else if(solutie(k)) afisare(k);
else {
k++;
x[k]=-1;/*initializam pe x[k] cu valoarea minima -1*/
}
}
}
void main()
{
citire();
back();
f.close();
}
12. Sa se afiseze toate posibilitatile de a inchide n paranteze corect.
Exemplu:
Pentru n=6 se va afisa:
((()))
(()())
(())()
()(())
()()()
Vom codifica cu 0 parantezele deschis si cu 1 parantezele inchise.
Observam ca valoarea minima este 0 si valoarea maxima este 1.
Avem solutie cand am inchis corect cele n/2 paranteze deschise si inchise.
Pentru a adauga un element la solutie avem urmatoarele restrictii:
- sirul de paranteze nu poate sa inceapa cu paranteza inchisa
- numarul de paranteze inchise nu poate fi mai mare ca numarul de paranteze deschise
- nu putem scrie mai multe de n/2 paranteze inchise sau paranteze deschise.
#include<fstream.h>
#include<stdlib.h>
ofstream f("parant.txt");
int x[50],k,valid,n,m;
void citire()
{cout<<"n=";cin>>n;
}
void posibil(int k,int &valid)
{
valid=1;
int pi=0;
int pd=0;
for (int i=1;i<=k;i++)
if(x[i]==0)pd++;
else pi++;
if(pd>n/2||pi>n/2)valid=0;/*nu pot sa apara in solutie mai mult de n/2 paranteze deschise sau inchise*/
if(k==1&&x[k]==1)valid=0; /*prima paranteza din sir nu poate fi paranteza inchisa*/
if(pi>pd)valid=0;/*nu pot sa apara in sir mai multe paranteze inchise decat deschise*/
}
int solutie(int k)
{/*Avem solutie cand avem in sir n/2 paranteze inchise si n/2 paranteze deschise*/
int pd=0;
int pi=0;
for (int i=1;i<=k;i++)
15
if(x[i]==0)pd++;
else pi++;
if(pd==n/2&&pi==n/2)return 1;
else return 0;
}
void afisare(int k)
{/*afisam solutia*/
for(int i=1;i<=k;i++)
if(x[i]==0) f<<"(";
else f<<")";
f<<endl;
}
void back()
{
k=1;
x[k]=-1;/*initializam x[k] cu valoarea minima-1*/
while(k>0)
{
valid=0;
while(!valid && x[k]<1)
{
x[k]=x[k]+1;
posibil(k,valid);
}
if(!valid)k--;
else if(solutie(k)) afisare(k);
else {
k++;
x[k]=-1;/*initializam elementul curent din solutie cu valoarea minima-1*/
}
}
}
void main()
{
citire();
back();
f.close();
}
14. Pentru n cuburi se cunosc dimensiunea laturii si culoarea.
Sa se afiseze toate posibilitatile de a construi turnuri din catem cuburi stiind ca:
- doua cuburi de aceasi culoare nu pot fi puse unul langa altul
- un cub cu latura mai mare nu poate fi pus peste un cub cu latura mai mica.
Exemplu:
n=4, m=2
Se vor citi in ordine dimensiunea laturii si culoarea
1: 4 rosu
2: 3 galben
3: 2 rosu
4: 1 verde.
Se va afisa:
1(4 rosu) 2(3 galben)
1(4 rosu) 4(1 verde)
2(3 galben) 3(2 rosu)
16
2(3 galben) 4(1 verde)
3(2 rosu) 4(1 verde)
Datele afisare au forma:
numarul cubului de la baza(dimensiune culoare) numarul cubului de deasupra (dimensiune culoare)
Observam ca: minimul=1 maximul=n.
Avem solutie cand asezam in turn m cuburi.
In functia posibil tinem cont de conditiile impuse in problema.
#include<fstream.h>
#include<stdio.h>
#include<string.h>
#include<iostream.h>
ofstream f("cuburi.txt");
int x[50],k,valid,n,m;
int dim[50];char cul[50][20];
void citire() /*citim datele de intrare*/
{cout<<"n=";cin>>n;
for(int i=1;i<=n;i++)
{ cout<<"dimensiunea laturii pentru cubul ",i,":";cin>>dim[i];
cout<<"culoarea cubului ",i,":";gets(cul[i]);
}
cout<<"m=";cin>>m;
}
void posibil(int k,int &valid)
{
valid=1;
for (int i=1;i<k;i++) if(x[i]==x[k])valid=0; /*acelasi cub nu poate fi pus in turn de doua ori*/
if(k>1)if(strcmp(cul[x[k-1]],cul[x[k]])==0) valid=0;/*doua cuburi alaturate nu pot avea aceiasi culoare*/
if(k>1)if(dim[x[k-1]]<dim[x[k]]) valid=0;/*un cub cu latura mai mare nu poate fi pus peste un cub cu latura
mai mica*/
}
int solutie(int k)
{/*avem solutie cand am reusit sa asezam in turn m cuburi*/
if(k==m)return 1;
else return 0;
}
void afisare(int k)
{/*afisam solutia specificand pentru fiecare cub dimensiunea laturii si culoare*/
for(int i=1;i<=k;i++)
f<<x[i]<<"("<<dim[x[i]]<<" "<<cul[x[i]]<<") ";
f<<endl;
}
void back()
{
k=1;
x[k]=0;
while(k>0)
{
valid=0;
while(!valid && x[k]<n)
{
x[k]=x[k]+1;
posibil(k,valid);
}
if(!valid)k--;
else if(solutie(k)) afisare(k);
else {
17
k++;
x[k]=0;
}
}
}
void main()
{
citire();
back();
f.close();
}
17. Sa se afiseze toate numerele cu cel mult n cifre care indeplinesc conditiile:
- au numai cifre pare
- cifrele nu se repeta.
Exemplu:
Pentru n=4 se va afisa:
18
2 240
20 2406
204 2408
2046 246
2048 2460
206 2468
2064 248
2068 2480
208 2486
2084 26
2086 .....
24
Observam ca:
- valoarea minima este 0 si valoarea maxima este 8 (pentru cifrele unui numar este 9). Voi alege varianta
cu valoarea maxima 9 desi recomand, ca in acest caz sa se tina cont de valoarea maxima;
- dupa afisarea unei solutii adaugarea de elemente la solutia deja construita continua
- elementele care fac parte din solutie respecta conditiile din problema fapt ce se trateaza in functia
posibil
- avem solutie daca numarul de elemente din solutie este cel mult n.
#include<fstream.h>
#include<stdio.h>
#include<string.h>
#include<iostream.h>
ofstream f("numere.txt");
int x[50],k,valid,n,m;
int dim[50];char cul[50][20];
void citire() /*citim numarul maxim de cifre pe care trebuie sa-l contina numarul*/
{cout<<"n=";cin>>n;
}
void posibil(int k,int &valid)
{
valid=1;
if(k==1&&x[k]==0)valid=0; /*un numar nu poate incepe cu 0*/
for(int i=1;i<=k-1;i++)if(x[i]==x[k])valid=0; /*cifrele trebuie sa nu se repete*/
if(x[k]%2!=0)valid=0;/*cifrele trebuie sa fie pare*/
}
int solutie(int k)
{/*avem solutie daca am depus in vectorul solutie cel mult n cifre*/
if(k<=n)return 1;
else return 0;
}
void afisare(int k)
{ /*afisam solutia*/
for(int i=1;i<=k;i++)
f<<x[i];
f<<endl;
}
void back()
{
k=1;
x[k]=-1;/*cea mai mica cifra este 0; initializam x[k] cu valoarea minima-1*/
while(k>0)
{
valid=0;
while(!valid && x[k]<9) /*cea mai mare cifra este 9 (recomand inlocuirea lui 9, in aceasta problema, cu
8 deoarece 8 este ultima cifra para*/
{
x[k]=x[k]+1;
posibil(k,valid);
}
if(!valid)k--;
else if(solutie(k)) {afisare(k);k++;x[k]=-1;} /*dupa ce se afiseaza o solutie se trece la urmatoarea
pastradu-se ca baza solutia precedenta*/
else {
k++;
x[k]=-1;/*initializam valoarea x[k] cu valoarea minima-1*/
}
}
}
void main()
{
citire();
back();
f.close();
}