Sunteți pe pagina 1din 21

1. Se dau n multimi fiecare multime cu cate m elemente.

Sa se afiseze elementele produsului


cartezian.
Exemplu:

n=3 m=4 solutii


111 114 .........
112 121
113 122

Prin urmare, valoarea minima este 1, valoarea maxima eate 4.


Observam ca avem solutie cand numarul de elemente din vectorul solutie este n.
Putem adauga un element in solutie indiferent ce elemente au fost depuse inainte (valid=1).
 #include<fstream.h>
ofstream f("cart.txt");
int x[50],k,valid,n,m;
void citire()//citirea datelor de intrare
{
cout<<"n=";cin>>n;
cout<<"m=";cin>>m;
}
void posibil(int k,int &valid)
{ /*nu exista conditii de continuitate. Orice element din multimea {1...m} poate fi adaugat la solutie*/
valid=1;
}
int solutie(int k)
{ /*avem solutie daca numarul de elemente din solutie este egal cu numarul de multimi*/
if(k==n)return 1;
    else return 0;
}

void afisare(int k)     }


{/*afisam solutia*/     if(!valid)k--;
for(int i=1;i<=k;i++) f<<x[i]<<" ";         else if(solutie(k)) afisare(k);
f<<endl;         else {
}         k++;
void back()         x[k]=0;
{         }
k=1; }
x[k]=0; }
while(k>0) void main()
{ {
    valid=0; citire();
    while(!valid && x[k]<m) back();
    { f.close();
    x[k]=x[k]+1; }
    posibil(k,valid);

pentru n=7 se va afisa

1111111 11113 11131


111112 111211 1114
111121 11122 112111

1
11212 115 1222
11221 121111 1231
1123 12112 124
11311 12121 ......
1132 1213
1141 12211

Observam ca numarul minim este 1 si numarul maxim este n.


Problema poate fi imbunatatita astfel incat multimile de solutii sa nu se repete.
Avem solutie daca suma numerelor din vectorul solutie este egal cu n.
Putem adauga o valoare in vectorul solutie daca si numai daca prin adaugare suma valorilor din vectorul
solutie nu depaseste n.

#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++;

for(int i=1;i<=k;i++)f<<x[i]<<" ";     if(!valid)k--;


f<<endl;         else if(solutie(k)) afisare(k);
}         else {
void back()         k++;
{         x[k]=0;
k=1;         }
x[k]=0; }
while(k>0) }
{ void main()
    valid=0; {
    while(!valid && x[k]<n) citire();
    { nr=0;
    x[k]=x[k]+1; back();
    posibil(k,valid); f.close();
    } }

2. Sa se afiseze un numar n ca suma de m numere naturale.

2
 Exemplu:

pentru n=6 si m=3 se afiseaza:

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

Observam ca valoarea minima este 1 si valoarea maxima este n.


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;
}
void afisare(int k)
{nr++;
for(int i=1;i<=k;i++)f<<x[i]<<" ";
f<<endl;
}
void back()
{
k=1;

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:

Pentru n=10 se afiseaza:

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

Valoarea minima este 1 valoarea maxima este n.


Avem solutie daca suma elementelor din vectorul solutie este n.
Putem adauga la vectorul solutie valoarea x[k] daca si numai daca este numar prim si prin adaugarea ei
suma elementelor din vector nu depaseste n.
 #include<fstream.h>
#include<math.h>
ofstream f("suma2.txt");
int x[50],k,valid,n,m,nr;
int prim(int n) /*verificam daca un numar este prim*/
{if(n<=1) return 0;
int i=2;
while(i<=n/2)
    if(n%i!=0)i++;
    else return 0;
return 1;
}
void citire()
{
cout<<"n=";cin>>n;
}
void posibil(int k,int &valid) /*x[k] poate fi adaugat la solutie daca este numar prim si daca prin adaugarea
lui suma elementelor din vectorul solutie nu depaseste n*/
{
int i;
valid=1;
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;

5
}

void back()         else {


{         k++;
k=1;         x[k]=0;
x[k]=0;         }
while(k>0) }
{ }
    valid=0; void main()
    while(!valid && x[k]<n) {
    { citire();
    x[k]=x[k]+1; nr=0;
    posibil(k,valid); back();
    } f.close();
    if(!valid)k--; }
        else if(solutie(k)) afisare(k);

4. Sa se scrie un numar n ca suma de numere naturale.


Exemplu:
pentru n=7 se va afisa

1111111 1132
111112 1141
111121 115
11113 121111
111211 12112
11122 12121
11131 1213
1114 12211
112111 1222
11212 1231
11221 124
1123 ......
11311

Observam ca numarul minim este 1 si numarul maxim este n.


Problema poate fi imbunatatita astfel incat multimile de solutii sa nu se repete.
Avem solutie daca suma numerelor din vectorul solutie este egal cu n.
Putem adauga o valoare in vectorul solutie daca si numai daca prin adaugare suma valorilor din
vectorul solutie nu depaseste n.

#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 

Observam ca valoarea minima este 1 si valoarea maxima este n.

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
}

void afisare(int k)     }


{nr++;     if(!valid)k--;
for(int i=1;i<=k;i++)f<<x[i]<<" ";         else if(solutie(k)) afisare(k);
f<<endl;         else {
}         k++;
void back()         x[k]=0;
{         }
k=1; }
x[k]=0; }
while(k>0) void main()
{ {
    valid=0; citire();
    while(!valid && x[k]<n) nr=0;
    { back();
    x[k]=x[k]+1; f.close();
    posibil(k,valid); }

6. Sa se scrie un numar n ca suma de numere prime.


Exemplu:
Pentru n=10 se afiseaza:
2 2 2 2 2  3 2 2 3  5 2 3 
2 2 3 3  3 2 3 2  5 3 2 
2 3 2 3  3 2 5  5 5 
2 3 3 2  3 3 2 2  73
2 3 5  3 5 2 
2 5 3  3 7 

Valoarea minima este 1 valoarea maxima este n.


Avem solutie daca suma elementelor din vectorul solutie este n.
Putem adauga la vectorul solutie valoarea x[k] daca si numai daca este numar prim si prin adaugarea ei
suma elementelor din vector nu depaseste n.
 #include<fstream.h>
#include<math.h>
ofstream f("suma2.txt");
int x[50],k,valid,n,m,nr;
int prim(int n) /*verificam daca un numar este prim*/
{if(n<=1) return 0;
int i=2;
while(i<=n/2)
    if(n%i!=0)i++;
    else return 0;
return 1;
}
void citire()
{
cout<<"n=";cin>>n;
}
void posibil(int k,int &valid) /*x[k] poate fi adaugat la solutie daca este numar prim si daca prin adaugarea
lui suma elementelor din vectorul solutie nu depaseste n*/
{
int i;
valid=1;

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;
}

void back()         else {


{         k++;
k=1;         x[k]=0;
x[k]=0;         }
while(k>0) }
{ }
    valid=0; void main()
    while(!valid && x[k]<n) {
    { citire();
    x[k]=x[k]+1; nr=0;
    posibil(k,valid); back();
    } f.close();
    if(!valid)k--; }
        else if(solutie(k)) afisare(k);

7. Sa se gaseasca toate posibilitatile de a construi un drapel din 3 culori stiind ca:


a) avem la dispozitie culorile galben, portocaliu, rosu, visiniu, verde, albastru;
b) in mijloc nu pot sa apara culorile galben si visiniu
c) culorile nu se repeta.
 Exemplu:
Problema nu are date generale de intrale. Problema ruleaza numai pentru datele date.

O parte din solutie este:

galben rosu portocaliu  galben albastru rosu 


galben rosu visiniu  galben albastru visiniu 
galben rosu verde  galben albastru verde 
galben rosu albastru  portocaliu galben rosu 
galben verde portocaliu  portocaliu galben visiniu 
galben verde rosu  portocaliu galben verde 
galben verde visiniu  portocaliu galben albastru 
galben verde albastru  portocaliu rosu galben 
galben albastru portocaliu  portocaliu rosu visiniu

 Numerotam culorile astfel:

9
1 - galben

2 - portocaliu

3 - rosu

4 - visiniu

5 - verde

6 - albastru.

Observam ca valoarea minima este 1 si valoarea maxima este 6.

Avem solutie cand numarul de culori din drapel este 3.

X[k] poate fi adaugat la solutie daca:

- nu a mai aparut in drapel

- 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;

void posibil(int k,int &valid)

valid=1;

if(k==2) if(x[k]==2||x[k]==4) valid=0; /*in mijloc nu poate sa apara galben sau visiniu*/

for(int i=1;i<=k-1;i++) if (x[k]==x[i]) valid=0; /*culorile nu se repeta*/

int solutie(int k)     if(x[i]==1)f<<"galben ";

{ /*steagul trebuie sa aiba 3 culori*/     else if(x[i]==2)f<<"portocaliu ";

if(k==3) return 1;     else if(x[i]==3)f<<"rosu ";

    else return 0;     else if(x[i]==4) f<<"visiniu ";

}     else if(x[i]==5) f<<"verde ";

void afisare(int k)     else  f<<"albastru ";

{ f<<endl;

for(int i=1;i<=k;i++) }

10
void back()     if(!valid)k--;

{         else if(solutie(k)) afisare(k);

k=1;         else {

x[k]=0;         k++;

while(k>0)         x[k]=0;

{         }

    valid=0; }

    while(!valid && x[k]<6) /*6 este codul cel mai }

mare*/ void main()

    { {

    x[k]=x[k]+1; back();

    posibil(k,valid); f.close();

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

abcd bacd cabd dabc

abdc badc cadb dacb

acbd bcad cbad dbac

acdb bcda cbda dbca

adbc bdac cdab dcab

adcb bdca cdba dcba

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;
}

void afisare(int k)     posibil(k,valid);


{     }
/*Afisam solutia. s[x[i]] - elementul din sirul de     if(!valid)k--;
caractere aflat pe pozitia x[i]*/         else if(solutie(k)) afisare(k);
for(int i=1;i<=k;i++)         else {
    f<<s[x[i]];         k++;
f<<endl;         x[k]=-1;/*valoarea minima=0 - 1*/
}         }
void back() }
{ }
k=1; void main()
x[k]=-1;/*valoarea minima=0 - 1*/ {
while(k>0) citire();
{ n=strlen(s);
    valid=0; back();
    while(!valid && x[k]<n-1) f.close();
    { }
    x[k]=x[k]+1;
 10. Pe un CD trebuie inscriptionate n melodii numerotate 1...n. Sa se afiseze toate modalitatile de
inscriptionare a melodiilor pe CD stiind ca:
- melodiile nu se repeta
- melodia 2 nu este inscriptionata inate de melodia 1.
Exemplu:
pentru n=4 se va afisa:
1234 1423 3412
1243 1432 4123
1324 3124 4132
1342 3142 4312
Observam ca:
- valoarea minima este 1 si valoarea maxima este n.
- trebuie respectate conditiile din enunt. Vom exclude solutiile care nu sunt bune prin conditiile puse in
functia posibil.
- avem solutie cand s-au inscriptionat toate cele n melodii.
 

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();
}

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