Sunteți pe pagina 1din 11

TEMA BACKTRACKING

Bornea Elena Diana

-Laboratorul 4-

Care va fi valoarea maximă a variabilei globale nr în timpul execuţiei programului anterior?


(3) 7
b. Care este penultima soluţie afişată?
{2,3}

2. (Problema de generare a aranjamentelor) Fie S={s1,s2,...,sn} cu elemente de tipul întreg. Se cere să


se determine toate modalităţile de a aranja elementele în grupe de p elemente distincte, p<n.

#include<iostream>
using namespace std;
int st[10],n,k,p;
void init(int k)
{
st[k]=0;
}
int succesor(int k)
{ if(st[k]<n)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
int valid(int k)
{
for(int i=0;i<k;i++)
if(st[i]==st[k])
return 0;
return 1;
}
int solutie(int k)
{ return k==p-1;
}
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
void back(int k)
{ init(k);
while(succesor(k))
{
if(valid(k))
if(solutie(k))
tipar(k);
else
back(k+1);
}
}
int main()
{
cout<<"Dati n=";
cin>>n;
cout<<"Dati p=";
cin>>p;
back(0);
}
3. Să se implementeze problema de generare a combinărilor.
#include<iostream>
using namespace std;
int st[10],n,k,p;
void init(int k)
{
st[k]=0;
}
int succesor(int k)
{if(st[k]<=n-p+k)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
int valid(int k)
{
for(int i=0;i<k;i++)
if(st[i]==st[k])
return 0;
return 1;
}
int solutie(int k)
{ return k==p-1;
}
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
void back(int k)
{ init(k);
while(succesor(k))
{
if(valid(k))
if(solutie(k))
tipar(k);
else
back(k+1);
}
}
int main()
{
cout<<"Dati n=";
cin>>n;
cout<<"Dati p=";
cin>>p;
back(0);
}

4. Să se genereze toate aranjamentele de n luate câte p cu proprietatea că diferenţa în modul dintre


oricare două numere consecutive este cel puţin egală cu o valoare v citită de la tastatură.

#include<iostream>
using namespace std;
int st[10],n,k,p,v;
void init(int k)
{
st[k]=0;
}
int succesor(int k)
{ if(st[k]<n)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
int valid(int k)
{
if((abs(st[k+1]-st[k])>v)&&k>0)
return 0;
for(int i=0;i<k;i++)
if(st[i]==st[k])
return 0;
return 1;
}
int solutie(int k)
{ return k==p-1; }
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
void back(int k)
{ init(k);
while(succesor(k))
{
if(valid(k))
if(solutie(k))
tipar(k);
else
back(k+1);
}
}
int main()
{
cout<<"Dati n=";
cin>>n;
cout<<"Dati p=";
cin>>p;
cout<<"Dati v=";
cin>>v;
back(0);
}

5. Se citeşte un număr par și natural n. Se cere să se tipărească toate modurile de descompunere a


numărului ca sumă de numere pare, naturale distincte. Dacă numărul citit este impar, se va afișa
un mesaj de atenționare.

#include<iostream>
using namespace std;
int st[10],n,suma;
void init(int k)
{ st[k]=0; }
int succesor(int k)
{
if(st[k]<n-k+1)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
void tipar(int k)
{
for (int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
int solutie()
{ return n==suma; }
int valid(int k)
{
if (suma>n||st[k]%2==1)
return 0;
for(int i=0;i<k;i++)
if(st[i]==st[k])
return 0;

return 1;
}
void back(int k)
{
init(k);
while(succesor(k))
{ suma=suma+st[k];
if(valid(k))
{ if(solutie())
tipar(k);
else
back(k+1);
}
suma=suma-st[k];
}
}
int main()
{
do
{
cout<<"Dati n=";
cin>>n;
}while(n%2==1);
back(0);
}
6. Se citeşte un număr natural n. Se cere să se tipărească toate mulțimile de numere naturale mai
mici ca n care însumate sunt egale cu 2*n. Soluțiile care au aceleași elemente se vor scrie o singură
dată, iar numerele se pot repeta.

#include<iostream>
using namespace std;
int st[10],n,suma;
void init(int k)
{ st[k]=0; }
int succesor(int k)
{
if(st[k]<n-k+1)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
void tipar(int k)
{
cout<<"{ ";
for (int i=0;i<=k;i++)
cout<<st[i]<<" , ";
cout<<"}"<<endl;
}
int solutie()
{ return suma==2*n; }

int valid(int k)
{
if (suma>2*n)
return 0;
return 1;
}
void back(int k)
{
init(k);
while(succesor(k))
{ suma=suma+st[k];
if(valid(k))
{ if(solutie())
tipar(k);
else
back(k+1);
}
suma=suma-st[k];
}
}
int main()
{
cout<<"Dati n=";
cin>>n;
back(0);
}
-Laboratorul 5-

1. Avem la dispoziţie 6 culori: alb, galben, roşu, verde, albastru, negru. Să se precizeze toate
drapelele tricolore care se pot proiecta, ştiind că trebuie respectate regulile:
Orice drapel are culoarea din mijloc galben sau verde.
Cele trei culori de pe drapel sunt distincte.

#include<iostream>
using namespace std;
int st[10],n,k,p;
char culori[][10]={"alb","galben","rosu","verde","albastru","negru"};
void init(int k)
{
st[k]=0;
}
int succesor(int k)
{ if(st[k]<n)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
int valid(int k)
{
if(k==1&& (st[k]!=2 && st[k]!=4) )
return 0;
for(int i=0;i<k;i++)
if(st[i]==st[k])
return 0;
return 1;
}
int solutie(int k)
{ return k==p-1;
}
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<culori[st[i]-1]<<" ";
cout<<endl;

}
void back(int k)
{ init(k);
while(succesor(k))
{
if(valid(k))
if(solutie(k))
tipar(k);
else
back(k+1);
}
}
int main()
{
n=6;
p=3;
back(0);
}

2. Să se genereze toate soluțiile de 4 numere naturale dintr-un vector v[17]={1, 2, 3, 4, 5, 6, 8, 9,


10, 12, 13, 14, 18, 21, 24, 27, 33} care îndeplinesc simultan următoarele condiţii:
3 şi 6 nu se găsesc niciodată împreună în soluţie, dar nici 12 cu 18.
Vectorul soluţie conţine doar numere divizibile cu 3
Soluţiile vor fi crescător afişate pe ecran.

#include<iostream>
using namespace std;
int st[100],v[17]={1, 2, 3, 4, 5, 6, 8, 9,10, 12, 13, 14, 18, 21, 24, 27, 33},n,p;
int valid(int k)
{
if(st[k]%3!=0)
return 0;
for(int i=0;i<k;i++)
{
if(st[i]==3 && st[k]==6)
return 0;
if(st[i]==12 && st[k]==18)
return 0;
if(st[i]>st[k])
return 0;

}
return 1;
}
int solutie(int k)
{ return k==p-1;
}
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
void back(int k)
{
for(int i=0;i<n;i++)
{
st[k]=v[i];
if(valid(k))
if(solutie(k))
tipar(k);
else
back(k+1);
}
1. }
2. int main()
3. {
4. n=17,p=4;
5. back(0);
6. }

3. Se cere să se tipărească toate modurile de descompunere a lui n ca sumă de numere divizibile


cu 3. Suma se citeşte de la tastatură. Soluțiile sunt afișate în ordine strict crescătoare. (n=36)

#include<iostream>
using namespace std;
int st[10],n,suma;
void init(int k)
{ st[k]=0; }
int succesor(int k)
{
if(st[k]<n-k+1)
{
st[k]=st[k]+1;
return 1;
}
return 0;
}
void tipar(int k)
{
for (int i=0;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
int solutie()
{ return suma==n; }

int valid(int k)
{
if (suma>n)
return 0;
if(st[k]%3!=0)
return 0;
return 1;
}
void back(int k)
{
init(k);
while(succesor(k))
{ suma=suma+st[k];
if(valid(k))
{ if(solutie())
tipar(k);
else
back(k+1);
}
suma=suma-st[k];
}
}
int main()
{
cout<<"Dati n=";
cin>>n;
back(0);
}
4. Fie n număr natural nenul. Scrieți un program de generare a tuturor submulțimilor
mulțimii {1, 2, 3,..., n}.
Implementare: Pentru n=3, avem
Soluția: a[0]......a[n-1]
a[i] poate fi 0 (i nu aparține submulțimii) sau 1 (i aparține submulțimii)
Soluția Codificare
{} 0 0 0
{3} 0 0 1
{2} 0 1 0
{2,3} 0 1 1
{1} 1 0 0
{1,3} 1 0 1
{1,2} 1 1 0
{1,2,3} 1 1 1
a[k] poate fi 0 sau 1 (Codificarea este pb. produsului cartezian pentru a[3]={1,1,1})
Funcția valid() - nu este necesară
La tipărire se vor afișa doar valorile care au fost notate cu 1

5. Utilizând metoda backtracking se generează permutările cuvântului INFO. Dacă primele 3


soluții generate sunt: INFO, INOF, IFNO care este ultima soluție afișată?
OFNI

6. Utilizând metoda backtracking sunt generate numerele de 3 cifre, având toate cifrele
distincte şi cu proprietatea că cifrele aflate pe poziţii consecutive sunt de paritate diferită.
Ştiind că primele şase soluţii generate sunt, în această ordine, 103, 105, 107, 109, 123, 125, care
este a zecea soluţie generată? Afișați mai întâi primele 10 soluții, apoi restul de 10, etc.
Indicație: Primele soluții încep cu 1, iar pentru oprire se va folosi funcția getchar() definită în
biblioteca stdio.h
?

7.Câte numere cu exact două cifre pot fi construite folosind doar cifre pare distincte? (Exemplu
de numere cu două cifre pare: 02,…,20, …, 24, …, 42, etc.)
20

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