Sunteți pe pagina 1din 33

Fisa 1 backtracking

2. Sa se genereze toate permutarile multimii {1,2,....,n} in care 2 elemente vecine trebuie sa fie de paritate
diferita ( nu ambele pare/impare).

3. Sa se genereze toate permutarile lexicografice ale unui cuvint citit de la tastatura.


4. Sa se genereze toate permutarile multimii {a1,a2,... ,an }de numere intregi citite de la tastaura.

5. Sa se genereze toate permutarile multimii 1,3,5,...2n+1

6. Se citeste de la tastatura un numar intreg n. Sa se genereze toate sirurile formate din numerele de la 1
la n, astfel incit fiecare valoare sa apara o data intr-un sir , iar valorile pare sa se gaseasca intotdeauna la
locul lor ( 2 pe pozitia a 2-a din sir, 4 pe a 4-a pozitie, etc.).
7. Scrieti un program care citeste de la tastatura un numar natural nenul n (n<=20) si construieste toate
numerele formate din n cifre impare cu proprietatea ca oricare doua cifre alaturate dintr-un numar generat
sunt consecutive n multimea cifrelor impare.

8. determinare suma tuturor nr din 5 cifre impare distincte.

9. Sa se afiseze toate permutarile multimii {1,2,...,n} care au proprietatea ca pentru orice element x al
permutarii (exceptie primul) exista un element anterior lui avind valoarea x-1 sau x+1.
10. Se citeste un numar natural n si o permutare a multimii {1,2,...,n}. Sa se afiseze permutarile multimii
{1,2,...,n} in care oricare doua elemente alaturate nu au fost alaturate in permutarea citita (initial) . Ex. Pt n=
4 si permutarea 2 4 1 3 , o permutare care respecta regula este 3 4 1 2.

11. Se citeste un numar natural n. Sa se genereze toate cuvintele de n litere mici care nu au doua vocale
sau 2 consoane alaturate.

12. Se citeste un numar natural n. Afisati toate numerele formate din n cifre in care oricare doua cifre
alaturate au paritate diferita.
Ex. Pentru n=4 se vor obtine:
1010
...
1014
...
2103
...
9898
#include<iostream>
Int st[100], n, k;
Int cond(int k)
{(for (int i=1; <k-1; i++)
If(st[k]==st[i]) return 0;
{if (k>1)
If (st[k]%2==st[k-1]%2) return 0;
If(k==1 ) st[k]==0; return 0;

Return 1;}
Void tipar()
{for(int i=1; i<=n; i++) cout<<st[i];}
Void bt()
{k=1; st[k]=0;
While(k>0)
{if(st[k]<9) {st[k]++;
If (cond(k)){if (k==n) tipar();
Else {k++;
St[k]==1;}}} else k--;}}
Int main()
{cin>>n;
Bt();}

13. sa se genereze si sa se afiseze ntr-un fisier text toate numerele naturale formate din cifre impare
distincte si sa se calculeze suma numerelor astfel generate.
Int cond(int k)
{ for(int i=1; i<=k-1; i++)
If(st[i]==st[k]) return 0;
Return 1;}
Void tipar()
{int nr=0;
For(int i=1; i<=k; i++)
Nr=nr*10+st[i];
}
Void bt()
{k=1;
St[k]=-1;
While(k>0)
{if(st[k]<9){st[k]+=2;
If (cond(k))}
Fisa 2 backtracking

1. Un meniu la restaurant este format din 3 feluri de mincare. 4 preparate pentru felul 1, 5 pentru felul
2 si 3 pentru felul 3. Fiecare preparat are un pret si un numar de calorii. Sa se genereze toate
variantele de meniu astfel incit pretul total sa nu depaseasca valoarea S si numarul de calorii sa fie
maxim C.
2. Se considera n multimi, a[i]=numarul de elemente al multimii I (1<=i<=n). generare toate
submultimile care au suma elementelor S.
3. Sa se genereze toate numerele formate din cifre distinct si care au suma cifrelor S.
4. Sa se genereze toate cuvintele de 2n litere , din multimea {A,B,C,D} astfel incit sa nu existe 2 litere
alaturate identice iar litera A sa fie utilizata de n ori.
5. Se considera un sir de n numere natural a1,a2,an. Sa se genereze toate expresiile obtinute prin
intercalarea + - intre aceste numere astfel incit rezultatul expresiei sa fie pozitiv.
6. Sa se genereze toate numerele de n cifre care au in component p cifre x.

7. Sa se genereze toate numerele care au in baza 2 acelasi numar de cifre de 0 si 1 ca si numarul n


dat.
8. N personae sint asezate in sir. Dintre ele se elimina in mod aleatoriu p personae. Sa se genereze
toate variantele de rearanjare a celor n-p personae ramase astfel incit sa nu aiba aceeasi vecini ca
in sirul initial.
9. Sa se genereze toate variantele de construire a unor drapele , care sa contina 3 din cele 6 culori
disponibile: rosu,verde,alb,gri,mov,lila iar culoarea din mijloc sa nu fie lila sau verde.
10. Pentru n cuburi se cunosc lungimea laturii Li si culoarea sa Ci. Sa se genereze toate turnurile care
se pot forma cu m cuburi astfel incat cuburile din turn sa aiba laturile in ordine descrescatoare ( sa
nu se rastoarne) iar doua cuburi vecine sa nu aiba aceeasi culoare.
#include <iostream>

using namespace std;


int n,st[100],m;
struct cub{
int li;
string ci;
}cuburi[100];

void tipar(int k)
{
for(int i=m;i>=1;i--)
cout<<st[i]<<" ";
cout<<endl;
}

int cond(int k)
{
if(k>1)
{if(cuburi[st[k]].li>cuburi[st[k-1]].li)return 0;
if(cuburi[st[k]].ci==cuburi[st[k-1]].ci)return 0;

}
return 1;
}

void backtrack(int k)
{
for(int i=1;i<=n;i++)
{st[k]=i;
if(cond(k))
{if(k==m)
tipar(k);
else backtrack(k+1);}}
}

int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>cuburi[i].li>>cuburi[i].ci;
}

backtrack(1);

}
11. Se considera n obiecte. Sa se genereze toate variantele de grupare in multimi de m obiecte astfel
incit fiecare multime sa contina obiectul x sis a nu contina obiectul y ( 1<=x,y,m<=n).

12. Sa se genereze toate numerele care au in baza 2 n cifre dintre care k1 cifre de 0.
13. Gigica si Ninica au primi n obiecte .Pentru fiecare obiect se cunoaste pretul. Gigica trebuie sa
primeasca m din cele n obiecte iar Ninica va primi n-m obiecte. Sa se genereze toate variantele de
impartire a celor n obiecte astfel incit cei doi copii sa aiba obiecte de valoare totala egala.

Fisa 3 Backtracking recursiv


Sa se genereze toate permutarile multimii {1,,n}. #include <iostream>
using namespace std;
int st[50],n;
int cond(int k)
{
for(int i=1;i<=k-1;i++) if(st[k]==st[i]) return 0;
return 1;
}
void tipar(int k)
{
for(int i=1;i<=k;i++) cout<<st[i]<<' ';
cout<<endl;
}
void back(int k)
{
for(int i=1;i<=n;i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n;
back(1);
}

2. Sa se genereze toate combinarile de n elemente luate cite p.


3. Se considera n multimi . Fiecare multime i (1<=i<=n) contine m[i] elemente. Sa se afiseze produsul
cartezian al acestor multimi.
4. Sa se genereze toate functiile injective f:A->B , unde card(A)=m si card(B)=n. #include <iostream>
using namespace std;
int st[50],n,m;
int cond(int k)
{
for(int i=1;i<=k-1;i++) if(st[k]==st[i]) return 0;
return 1;
}
void tipar(int k)

{
for(int i=1;i<=m;i++) cout<<st[i]<<' ';
cout<<endl;
}
void back(int k)
{
for(int i=1;i<=n;i++)
{
st[k]=i;
if(cond(k))
{
if(k==m) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n>>m;
back(1);
}

5. Sa se genereze toate numerele de n cifre care se divid prin k1. #include <iostream>
using namespace std;
int st[50],n,k1;
int cond(int k)
{
if((k==1)&&(st[k]==0)) return 0;
return 1;
}
void tipar(int k)
{
int nr=0;
for(int i=1;i<=k;i++)
nr=nr*10+st[i];
if(nr%k1==0) cout<<nr<<endl;
}
void back(int k)
{
for(int i=0;i<=9;i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n>>k1;
back(1);

}
6. Sa se genereze toate numerele de n cifre si cu k1 cifre de 1#include <iostream>
using namespace std;
int st[100],n,k1;
void tipar(int k)
{
for(int i=1;i<=k;i++) cout<<st[i]<<" ";
cout<<endl;
}
int cond(int k)
{
if(k==n)
{
int s=0;
for(int i=1;i<=k;i++)
if(st[i]==1) s+=1;
if(s!=k1) return 0;
}
return 1;
}
void back(int k)
{
for(int i=1;i<=9;i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n>>k1;
back(1);
}
.
7. Sa se genereze toate numerele de n cifre supermultiple de k1. Un numr este supermultiplu de k ,
dac att numrul ct i toate numerele obinute din el prin tierea succesiv a cifrelor sale
ncepnd cu cifra unitilor sunt multiple de k.Pentru n=3 i k=2 numrul 246 este supermultiplu
de k deoarece numerele 246 , 24 , 2 sunt multiple de k . #include <iostream>
using namespace std;
int st[100],n,k1;
void tipar(int k)
{
for(int i=1;i<=k;i++) cout<<st[i]<<" ";
cout<<endl;

}
int cond(int k)
{
if(st[k]%k1!=0)return 0;
return 1;
}
void back(int k)
{
for(int i=1;i<=9;i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n>>k1;
back(1);
}
8. Sa se genereze toate numerele care au in baza 2 acelasi numar de cifre de 0 si 1 ca si numarul n dat.
#include <iostream>
#include <math.h>
using namespace std;
int st[100],n,k1,s1,s0,lg;
void tipar(int k)
{
int s11=0, s00=0, nr=0;
for(int i=1;i<=k;i++)
{
if(st[i]==0) s00++;
else s11++;
}
if((s11==s1)&&(s00==s0))
{
for(int i=1;i<=lg;i++) nr=nr+pow(2,i-1);
cout<<nr<<endl;
}
}
int cond(int k)
{
int s11=0, s00=0;
for(int i=1;i<=k;i++)
{
if(st[i]==0) s00++;
else s11++;

}
if(s00>s0) return 0;
if(s11>s1) return 0;
return 1;
}
void back(int k)
{
for(int i=0;i<=1;i++)
{
st[k]=i;
if(cond(k))
{
if(k==lg) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n;
while(n)
{
if(n%2==1) s1++;
else s0++;
n/=2;
}
lg=s1+s0;
back(1);
}
9. Sa se genereze toate permutarile de n elemente unde pentru orice i intre 2 si n exista j intre 1 si i ai
|st[i]-st[j]|=1.
10. Pentru vectorul v(n) sa se genereze toate subsirurile cresc de lung [n/5]. #include <iostream>
#include <stdlib.h>
using namespace std;
int v[100],st[100],n,i1;
void tipar(int k)
{
for(int i=1;i<=k;i++)
cout<<v[st[i]]<<" ";
cout<<endl;
}
int cond(int k)
{

for(int i=1;i<k;i++)
if(st[k]==st[i]) return 0;
if(k>1)

if(v[st[k]]<v[st[k-1]]) return 0;

return 1;
}
void backtrack(int k)
{
for(int i=1;i<=n;i++)
{
st[k]=i;
if(cond(k))
if(k==i1) tipar(k);
else backtrack(k+1);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>v[i];
i1=n/5;
backtrack(1);

}
11. Pentru vectorul v(n) sa se genereze toate submultimile sale astfel incit suma elem submultimilor sa
fie S.
12. Sa se calculeze p(1)+p(2)+....+ p(k) unde p(k) reprezinta numarul subsirurilor cresc de lung k
dintr-un vector v cu n e elemente numere intregi .
13. Fie n un numar natural. Sa se det numarul maxim obtinut prin eliminarea din n a k1 cifre.
14. Fie matricea a(nxn)cu elemente numere intregi. Sa se det cea mai mare suma a n valori luate din
linii si coloane diferite.
15. Sa se genereze toate matricile binare nxn (cu elemente 0 si 1)astfel incit fiecare coloana sa contina
exact o valoare de 0 si restul 1.
16. Sa se genereze toate numerele formate doar din cifrele 1,3,5,7,9 avind cifre impare distincte si
suma acestor numere.
#include <iostream>
using namespace std;
int n,st[100];

void tipar(int k)
{
for(int i=1;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}

int cond(int k)
{
for(int i=1;i<k;i++)
{if(st[k]==st[i])return 0;
}

return 1;
}
void backtrack(int k)
{
for(int i=1;i<=9;i+=2)
{
st[k]=i;
if(cond(k))
if(k==5)
tipar(k);
else
backtrack(k+1);}
}

int main()
{

backtrack(1);
}
17. Pentru un cuvint dat sa se afiseze toate cuvintele ce contin literele distincte ale cuvintului
initial si nu contin 2 vocale/consoane alaturate. #include <iostream>
#include <string.h>
using namespace std;
int n,st[100];
char cuv[100],v[]="aeiou";
void tipar(int k)
{
for(int i=0;i<=k;i++)
cout<<cuv[st[i]]<<" ";
cout<<endl;
}
int cond(int k)
{
for(int i=0;i<k;i++)
if(cuv[st[k]]==cuv[st[i]])return 0;
if((strchr("aeiou",cuv[st[k-1]])!=NULL)==(strchr("aeiou",cuv[st[k]])!=NULL)) return 0;
return 1;
}

void backtrack(int k)
{
for(int i=0;i<n;i++)
{
st[k]=i;
if(cond(k))
if(k==n-1)
tipar(k);
else
backtrack(k+1);}
}

int main()
{
cin>>cuv; n=strlen(cuv);
backtrack(0);
}
18. Pe o mare sint n porturi. Stationarea intr-un port se taxeaza cu un anumit cost. Sa se stabileasca
toate voiajele distincte prin p porturi (p<=n) astfel incit sa nu se depaseasca un cost total dat.
Porturile au denumirile de maxim 16 caractere, iar costurile sint numere reale. Fisierul de intrare
port.in are urmatoarea forma:
np
nume-port-1 cost-port-1
...
nume-port-n cost-port-n
cost-total-maxim #include <iostream>
using namespace std;
int st[50],n,ct,x;
struct port
{
float c;
char nume[16];
};
port p[30];
int cond(int k)
{
for(int i=1;i<=k-1;i++) if(st[k]==st[i]) return 0;
int s=0;
for(int i=1;i<=k;i++) s+=p[st[i]].c;
if(s>ct) return 0;
return 1;
}
void tipar(int k)
{

int s=0;
for(int i=1;i<=k;i++) s+=p[st[i]].c;
if(s==ct)
for(int i=1;i<=k;i++) cout<<p[st[i]].nume<<' '<<p[st[i]].c<<' ';
cout<<endl;
}
void back(int k)
{
for(int i=1;i<=n;i++)
{
st[k]=i;
if(cond(k))
{
if(k==x) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n>>x;
for(int i=1;i<=n;i++) cin>>p[i].nume>>p[i].c;
cin>>ct;
back(1);
}
19. Sa se genereze toate modurile in care se poate perfora un bilet de autobuz in 3 puncte( un bilet are 9
puncte de perforare posibile). #include <iostream>
using namespace std;
int st[50];
int cond(int k)
{
if(k>1) if(st[k]<=st[k-1]) return 0;
return 1;
}
void tipar(int k)
{
for(int i=1;i<=9;i++)
{
int ok=0;
for(int j=1;j<=k;j++)
if(st[j]==i) ok=1;
if(ok==0) cout<<'*'<<' ';
else cout<<i<<' ';
if(i%3==0) cout<<endl;
}
cout<<endl;
}
void back(int k)

{
for(int i=k;i<=k+6;i++)
{
st[k]=i;
if(cond(k))
{
if(k==3) tipar(k);
else back(k+1);
}
}
}
int main()
{
back(1);
}

20. Sa se genereze toate numerele de n cifre incepind de la 11...1 pina la m1 m2 ....mn. De ex pentru n=3,
si vectorul m={7,5,3} se vor genera:111,112,113, 121,122,123,131, 132 ,133,141,142, 143,151, 152,
153,211,212,213,221,222,223,. . . ,753.
//produs cartezian recursiv
#include <iostream>
using namespace std;
int st[50],n,m[20];
int cond(int k)
{
return 1;
}
void tipar(int k)
{
for(int i=1;i<=k;i++) cout<<st[i];
cout<<endl;
}
void back(int k)
{
for(int i=1;i<=m[k];i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar(k);
else back(k+1);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>m[i];
back(1);

21. Sa se genereze toate variantele de asezare a n ture pe o tabla de sah astfel incit sa nu existe oricare
doua ture care sa se atace.
22. Sa se genereze toate variantele de asezare a n regine pe o tabla de sah astfel incit sa nu existe
oricare doua regine care sa se atace.
#include <iostream>
#include <cmath>
using namespace std;
int st[100],n,ok;
int cond(int k)
{ for(int i=1;i<k;i++)
if(st[k]==st[i]) return 0;
for(int i=1;i<k;i++)
if(abs(st[k]-(double)st[i])==abs(i-(double)k)) return 0;
return 1;
}
void tipar(int k)
{
for(int i=1;i<=k;i++)
{for(int j=1;j<=k;j++)
if(st[i]==j)cout<<'R';
else {cout<<'*';
} cout<<endl;}
cout<<endl;
}
void backtrack(int k)
{
for(int i=1;i<=n;i++)
{st[k]=i;
if(cond(k))
{if(k==n) {tipar(k);ok=1;}
else backtrack(k+1);}}
}
int main()
{
cin>>n;
backtrack(1);
}
*. Sa se genereze toate variantele de asezare a n cai pe o tabla de sah astfel incit sa nu existe oricare doi
cai care sa se atace.
23. Sa se genereze toate sirurile crescatoare de lungime lg formate din divizori ai lui n ( n si lg numere
naturale <=999). Daca nu exista solutie se va afisa un mesaj corespunzator. #include <iostream>
using namespace std;
int st[100],n,v[100],k1,d,ok=0;
int cond(int k)
{

for(int i=1;i<k;i++)
if(st[i]==st[k]) return 0;
if(k>1)
if(st[k]<st[k-1]) return 0;
return 1;
}
void tipar(int k)
{
for(int i=1;i<=k;i++)
cout<<v[st[i]]<<" ";
cout<<endl;
}
void backtrack(int k)
{
for(int i=1;i<=d;i++)
st[k]=i;
if(cond(k))
if(k==k1) {tipar(k);ok=1;}
else backtrack(k+1);
}
int main()
{
cin>>n>>k1;
d=1;
v[1]=1;
for(int i=2;i<=n/2;i++)
if(n%i==0)v[++d]=i;
v[++d]=n;
backtrack(1);
if(ok==0) cout<<"Nu exista solutii";
}
Fisa 4 backtracking
Toate partitiile unei multimi ai fiecare clasa dintr-o partitie sa aiba ac numar de elemente. #include
<iostream>
using namespace std;
int st[50],n;
int cond(int k)
{
if((k==1)&&(st[k]!=1)) return 0;
return 1;
}
void tipar(int k)
{
int v[50]={0};
int m=maxim1(k);

for(int i=1;i<=m;i++)
{
for(int j=1;j<=k;j++) v[st[j]]++;
int ok=1;
for(int j=1;j<=m-1;j++) if(v[j]!=v[j+1]) ok=0;
if(ok)
for(int i=1;i<=m;i++)
{
cout<<'{';
for(int j=1;j<=k;j++)
if(st[j]==i) cout<<j;
cout<<'}';
}
cout<<endl;
}
}
void back(int k)
{
for(int i=1;i<=maxim1(k-1)+1;i++)
{
st[k]=i;
if(cond(k))
{
if(k==n) tipar (k);
else back(k+1);
}
}
}
int main()
{
cin>>n;
back(1);
}
1.
2. Se doreste efectuarea unei plati de suma s cu n tipuri de monezi. Pentru fiecare moneda se cunoaste
valoarea ei si numarul de monezi disponibile. Sa se genereze daca este posibil, toate variantele de plata.
3. Se doreste efectuarea unei plati de suma s cu n tipuri de monezi. Pentru fiecare moneda se cunoaste
valoarea ei iar numarul de monezi este nelimitat. Sa se genereze daca este posibil, toate variantele de
plata.
4. Sa se genereze toate variantele de descompunere a numarului natural n in suma de numere prime.
5. Sa se genereze toate variantele de descompunere a numarului natural n in suma de 3 si 5.
6. Se considera n intrebari. Pt fiecare intrebare se cunoaste punctajul ei. Generare toate chestionarele care
au intre a si b
intrebari distincte si un punctaj total intre p si q.
7. Sa se genereze toate sirurile de n (par) paranteze care se inchid corect.
8. Sa se genereze toate variantele de asezare in linie a m ciini si n pisici astfel incit sa nu existe o pisica
asezata intre 2 ciini. #include <iostream>
using namespace std;

void backtrack(int k)
{
for(int i=0;i<=1;i++)
st[k]=i;
if(cond(k))

if(k==n+m) {tipar(k);}
else backtrack(k+1);
}
int main()
{
cin>>n>>m;s
backtrack(1)
}
9. Se considera n piese de domino citite ca perechi de numere naturale, fiecare pe cate un rand de intrare.
Sa se afiseze cel
mai lung lant domino care se poate forma cu piesele date, fara a roti piesele. (Un lant domino se
alcatuieste din piese
domino astfel incat o piesa este urmata de alta a carei prima jumatate coincide cu jumatatea a doua a
piesei curente.) #include <iostream>
using namespace std;
int st[100],n,maxi=0,t[100];

struct domino{
int c1,c2;
}piese[100];
void tipar(int k)
{
if(k>maxi)
{
maxi=k;
for(int i=1;i<=k;i++)
t[i]=st[i];

}
}
int cond(int k)
{
for(int i=1;i<k;i++)
if(st[k]==st[i])return 0;
if(k>1)
if(piese[st[k-1]].c2!=piese[st[k]].c1) return 0;
return 1;
}

void backtrack(int k)
{
for(int i=1;i<=n;i++)
{st[k]=i;
if(cond(k))
{if(k<=n)
tipar(k);
backtrack(k+1);}}

}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>piese[i].c1>>piese[i].c2;
backtrack(1);
cout<<maxi<<endl;
for(int i=1;i<=maxi;i++)
cout<<"( "<<piese[t[i]].c1<<" "<<piese[t[i]].c2<<" )";
}
Ex:pentru n=6 si (1,2) (2,3) (3,5) (1,3) (3,4) (4,5) se va afisa: (1, 2) (2, 3) (3, 4) (4, 5)
10. Se considera n piese de domino citite ca perechi de numere naturale, fiecare pe cate un rand de
intrare. Se citeste apoi
un numar natural x. Sa se afiseze toate solutiile de aranjare a acestor piese intr-un lant domino de lungime
x, cu
posibilitatea de a roti piesele. (Un lant domino se alcatuieste din piese domino astfel incat o piesa este
urmata de alta a
carei prima jumatate coincide cu jumatatea a doua a piesei curente.)
Ex: pentru n=6 , x=3 si (1 2) (1 3) (3 4) (2 3) (3 5) (4 5) se va afisa :
(1 2) (2 3) (3 1) (2 1) (1 3) (3 2) (2 1) (1 3) (3 5) (5 4) (4 3) (3 2) (5 4) (4 3) (3 5)
11. Vectorul v contine n elemente numere naturale. Sa se determine si sa se afiseze primele p valori
maxime. #include <iostream>
using namespace std;
int st[100],n,v[100],p,maxi[100];
void tipar(int k)
{
for(int i=1;i<=k;i++)
if(v[st[i]]>maxi[i])maxi[i]=v[st[i]];
}
int cond(int k)
{ if(k>1){for(int i=1;i<k;i++)
if(st[k]==st[i])return 0;
if(k>1)
for(int i=1;i<=k;i++)
if(v[st[k]]>v[st[k-1]]) return 0;}
return 1;
}

void backtrack(int k)
{
for(int i=1;i<=n;i++)
{st[k]=i;
if(cond(k))
if(k==p) {tipar(k);}
else backtrack(k+1);}
}

int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
{cin>>v[i];maxi[i]=0;
}
backtrack(1);
for(int i=1;i<=p;i++)
cout<<maxi[i]<<" ";
}
12. Dintr-un grup de n persoane, dintre care p sint copii se doreste generarea tuturor delegatiilor de k1
persoane dintre care l copii.
13. N puncte in plan sint date prin coordonatelele lor numere intregi. Sa se genereze toate variantele de
unire a lor prin p
drepte astfel incit multimea punctelor de intersectie ale acestor drepte sa fie inclusa in multimea celor n
puncte.
14. N intervale sint date prin limitele inferioara/superioara. Sa se genereze toate secventele de interval
astfel incit oricare 2
intervale din secvente sint disjuncte.
15. N persoane trebuie sa participe la o masa rotunda. Dintre aceste n persoane k1 sint de la firme
concurente. Sa se
genereze toate variantele de asezare la masa rotunda astfel incit sa nu existe alaturat 2 persoane de la
firme concurente.
16. O persoana are un rucsac cu care poate transporta o greutate maxima G. Aceasta persoana are n
obiecte pentru care se
cunosc greutatile gi si un cost ci ( reprezentind cistigul obtinut pentru transportul obiectului i, 1<=i<=n). Sa
se
genereze toate variantele de transport al cit mai multor obiecte (din cele n) , pentru un transport astfel incit
obiectele
incarcate in rucsac sa nu depaseasaca greutatea G a rucsacului. Pentru fiecare transport sa se determine
si cistigul
obtinut. Ce transport are cistig maxim si din ce obiecte este format.
17. Un comis voiajor trebuie sa viziteze n orase. Initial el se afla in orasul x. Comis voiajorul doreste sa nu
viziteze de 2 ori
acelasi oras , iar la intoarcere sa revina in acelasi oras x. Sa se genereze toate variantele de calatorie
posibile, cunoscind
legaturile existente intre orase. De exemplu pentru n=5, x=1 si avind legaturi intre orasele: 1-2,1-3,1-4,15,2-4,2-5,3-5,
variante de calatorie avem: (1,3,5,2,4,1) , (1,4,2,5,3,1).
18. Un comis voiajor trebuie sa viziteze n orase. Initial el se afla in orasul x. Comis voiajorul doreste sa nu
viziteze de 2 ori
acelasi oras , iar la intoarcere sa revina in acelasi oras x. Orasele sint legate intre ele prin drumuri directe
sau indirecte
(prin intermediul altui oras). De exemplu orasele A si Btr sint Sa se determine traseul cel mai scurt de
vizitare.
Fisa 5 back in plan
1. Pe o tabla de sah de dimensiunea nxn in coltul stinga-sus se gaseste un cal
care trebuie sa parcurga toata tabla de sah, prin fiecare patrat al tablei
putind trece o singura data.Sa se genereze toate solutiile de parcurgere a
tablei. #include<iostream>
#include<conio.h>

using namespace std;

int a[30][30], n;

void afisare ()
{ int i, j;
for (i=1; i<=n; i++)

{for (j=1; j<=n; j++) cout<<a[i][j]<<" ";


cout<<endl;}
cout<<endl;
}

void bt (int x, int y, int k)


{if (k==n*n+1) afisare();
else if ((1<=x&&x<=n)&&(1<=y&&y<=n))
if (a[x][y]==0) {a[x][y]=k;
bt(x-2, y-1, k+1);
bt(x-2, y+1, k+1);
bt(x-1, y-2, k+1);
bt(x-1, y+2, k+1);
bt(x+1, y-2, k+1);
bt(x+1, y+2, k+1);
bt(x+2, y-1, k+1);
bt(x+2, y+1, k+1);
a[x][y]=0;};
}
int main()
{cin>>n;
bt(1,1,1);
getche();

}
2. Un labirint se codifica printr-o matrice nXm in care pozitii libere sint
codificate cu 0 iar zidurile sint codificate cu -1. In pozitia x,y se afla un
robot care se poate deplasa pe cele patru directii N,S,V,E. Sa se afiseze
toate drumurile prin care robotul poate iesi din labirint. Care este cel mai
scurt drum?
#include<iostream>
#include<fstream>

using namespace std;


int a[30][30], m, n, x0, y0;
ifstream f("robot.txt");
void citire ()
{f>>m>>n>>x0>>y0;
for (int i=1; i<=m; i++)
for (int j=1; j<=n; j++)
f>>a[i][j];
}
void afisare ()
{
for (int i=1; i<=m; i++)
{for (int j=1; j<=n; j++) cout<<a[i][j]<<" ";
cout<<endl;}
cout<<endl;
}

void bt(int x, int y, int k)


{if ((1<=x&&x<=m)&&(1<=y&&y<=n))
{
if (a[x][y]==0)
{a[x][y]=k;
bt(x-1, y, k+1);
bt(x, y-1, k+1);
bt(x, y+1, k+1);
bt(x+1, y, k+1);

a[x][y]=0;
}

}
else afisare();
}

int main()
{citire();
bt(x0, y0, 100);
//
afisare();
}
3. Pe un teren nxm in pozitia 1,1 se gaseste un automobil ce trebuie sa ajunga in
pozitia n,m.automobilul se poate deplasa doar in directiile N,S,E,V. Terenul
este marcat cu obstacole.Sa se afiseze toate traseele parcurse( atat in
matrice cat si ca sir de pozitii).
4. Un munte este memorat ca o matrice n*m in care fiecare pozitie reprezinta
altitudinea din acel loc. In pozitia x,y se afla un alpinist ce se poate
deplasa pe cele 8 directii N,N-E,E,E-S,S,S-V,V,N-V doar daca altitudinea
punctului vecin este mai mare sau egala decat cea pe care se afla alpinistul.
In matrice exista o singura valoare maxima reprezentind altitudinea varfului
muntelui. Sa se genereze toate traseele de escaladare a muntelui stiind ca
alpinistul poate ajunge in varf fara a trece de 2 ori prin aceeasi pozitie.

Fisa de lucru Greedy

1. Avind la dispozitie o multime A cu n elemente sa se determine o submultime S cu numar maxim de


elemente astfel incit suma elementelor submultimii S sa fie maxima.
#include <iostream>
using namespace std;
int n,m,a[100];
void sort()
{
for(int i=1;i<n;i++)
for(int j=i+1;i<=n;j++)
if(a[i]<a[j])
{int aux =a[i];
a[i]=a[j];
a[j]=aux;
}
}
void greedy()

{ sort();
int s;
for(int i=1;i<=m;i++)
s+=a[i];
cout<<s;
}

int main()
{
int n,a[100];
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
greedy();

}
2. Avind la dispozitie o multime A cu n elemente sa se determine o submultime S de m elemente astfel
incit suma elementelor submultimii S sa fie maxima.
3. Se citete un ir de n numere ntregi. S se aleag din ir un numr maxim de elemente astfel nct
produsul lor s fie maxim.
4. Maximizarea Expresiei. Se da o multime cu n numere ntregi nenule B={b1, b2, , bn} si o multime cu
m numere ntregi nenule A={ a1, a2, , am} . (m<n). S se determine o submulime a mulimii B care
maximizeaz valoarea expresiei E=a1*x1 + a2*x2 + + am*xm, unde xi sint elemente ale multimii
B. //1.maximizarea unei expresii.var2
#include <iostream>
using namespace std;
void citire(int &n, int v[50])
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>v[i];
}
void sortare(int &n, int v[50])
{
int c=0;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(v[i]<v[j])
{
c=v[i];
v[i]=v[j];
v[j]=c;
}
}
void greedy(int a[50], int b[50], int m, int n)
{
int e=0,aux[50]={0};

int i=1;
while((b[i]>0)&&(i<=n))
{
e+=b[i]*a[i]; aux[i]=1;
i++;
}
int j=m;
while(i<=n)
{
e+=a[j]*b[i]; aux[i]=1;
i++;j--;
}
cout<<e<<endl;
for(i=1;i<=m;i++)
{
if(aux[i]) cout<<a[i]<<' ';
}
}
int main()
{
int n,m,a[50],b[50];
citire(m,a);
citire(n,b);
sortare(m,a);
sortare(n,b);
greedy(a,b,m,n);
}

5. La un festival sint programate sa aiba loc intr-o zi n spectacole. Pentru fiecare spectacol se cunoaste
ora de inceput si ora de sfirsit. O persoana doreste sa intocmeasca o lista cu cit mai multe spectacole
pe care sa le vizioneze, astfel incit acestea sa nu se suprapuna. Ajutati-l.
using namespace std;
int s[2][10],o[10],n,i,h1,m1,h2,m2,ora;
void sortare() //sortare prin metoda bulelor
{int gata,m,i;
do
{gata=1;
for(i=1;i<n;i++)
if(s[1][o[i]]>s[1][o[i+1]])
{m=o[i];
o[i]=o[i+1];
o[i+1]=m;
gata=0;
}
}
while(!gata);
}
int main()

{cout<<"n= ";cin>>n;
for(i=1;i<=n;i++)
{o[i]=i;
cout<<"Ora de inceput pentru spectacolul "<<i<<" (hh mm)= ";
cin>>h1>>m1;
s[0][i]=h1*60+m1;
cout<<"Ora de sfarsit pentru spectacolul "<<i<<" (hh mm)= ";
cin>>h2>>m2;
s[1][i]=h2*60+m2;
}
sortare();
cout<<"Ordinea spectacolelor este: "<<endl<<o[1]<<endl;
ora=s[1][o[1]];
for(i=2;i<=n;i++)
{if(s[0][o[i]]>=ora)
{cout<<o[i]<<endl;
ora=s[1][o[i]];
}}}
6. Consideram ca avem n obiecte pentru care cunoastem greutatile gi si costurile ci. Avind la dispozitie un
rucsac de capacitate G dorim sa transportam cit mai multe din cele n obiecte astfel incit sa nu depasim
G dar sa obtinem si un cistig maxim. Daca un obiect nu incape in totalitate in rucsac il putem fractiona.
7. Avem la dispozitie n tipuri de monezi ( de valori diferite) intr-un numar nelimitat de exemplare. Dorim sa
realizam efectuarea unei plati de suma S, astfel incit sa folosim cit mai putine monezi.
Void citire()
{cin>>n>>s;
for(int i=1; i<=n; i++) cin>>a[i];}
void sortare()
{
for(int i=1;i<n;i++)
for(int j=i+1;i<=n;j++)
if(a[i]<a[j])
{int aux =a[i];
a[i]=a[j];
a[j]=aux;
}
Void greedy()
{int i=1;
While(s>0)
{IF(s/v[i]>0) cout<<s/v[i]<<bacnote de valoare<<v[i];
If (v[i]==1) cout <<bacnota de valoare<<v[i];
Else s=s-s/v[i]*v[i];} i++;}}
int main()
{citire ();
Sortare();
greedy();

}
8. Un comis voiajor trebuie sa viziteze n orase. El pleaca din orasul x, trece prin celelalte orase si vrea sa
se intoarca tot in orasul x. Fiecare oras poate fi vizitat o singura data. Stiind distantele dintre orase ( o
valoare intreaga pozitiva sau 0 daca nu exista drum direct ) sa se determine traseul de parcurgere
astfel incit lungimea lui sa fie minima.
#include<iostream>
#include<fstream>
using namespace std;
int d,x,oc,viz[50],a[50][50],nr,n,i,j,minim,j1;
void greedy()
{
oc=x;
viz[oc]=++nr;
for(i=1;i<=n-1;i++)
{
minim=1000;
for(j=1;j<=n;j++)
if((a[oc][j]!=0)&&(viz[j]==0)&&(a[oc][j]<minim))
{
minim=a[oc][j];
j1=j;
}
d+=a[oc][j];
viz[j1]=++nr;
oc=j1;
}
d+=a[oc][x];
}
int main()
{
ifstream f("in.txt");
f>>n>>x;
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
{
f>>a[i][j];
a[j][i]=a[i][j];
}
greedy();
cout<<"Ordinea oraselor este "<<endl;
for(i=1;i<=n;i++)
if(viz[i]!=1)
cout<<"orasul "<<i<<" a fost vizitat al "<<viz[i]<<"-lea"<<endl;
else cout<<"orasul "<<i<<" a fost vizitat primul"<<endl;
f.close();

return 0;
}
\

9.La un cabinet medical trebuie sa fie programati intr-o zi n pacienti. Pentru fiecare pacient se cunoaste
durata consultatiei. Sa se determine o ordine de programare a pacientilor astfel incit timpul mediu de
asteptare pentru consultatii sa fie minim.
*/
#include <iostream>
using namespace std;
int n;
struct multime{
int mini;int asteptare ;int nr;
}multimi[100];
void sort()
{
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(multimi[i].mini>multimi[j].mini)
{multime aux =multimi[i];
multimi[i]=multimi[j];
multimi[j]=aux;
}
}
void greedy()
{sort();
flo at s;
for(int i=2;i<n;i++)
for(int j=1;j<i;j++)
multimi[i].asteptare+=multimi[j].mini;
for(int i=1;i<=n;i++)
s+=multimi[i].asteptare;
cout<<s;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{cin>>multimi[i].mini;multimi[i].nr=i;multimi[i].asteptare=0;}
greedy();
}
9.

10. Se cunosc limitele [li,ls] pentru n intervale. Sa se determine cite multimi de intervale reunite disjuncte
avem.
#include <iostream>
using namespace std;
int n;
struct interval
{
int li;
int ls;
int nr;
}intervale[100];
11. Se cunosc limitele [li,ls]) pentru n intervale.. Sa se determine o multime de intervale care sa nu se
intersecteze.
#include <iostream>
using namespace std;
int n;
struct interval
{
int li;
int ls;
int nr;
}intervale[100];

int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>intervale[i].li>>intervale[i].ls;

for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
{if(intervale[j].li<intervale[i].li)
{
interval aux=intervale[i];
intervale[i]=intervale[j];
intervale[j]=aux;
}

if(intervale[j].li==intervale[i].li)
if(intervale[i].ls<intervale[j].ls)
{interval aux=intervale[i];
intervale[i]=intervale[j];
intervale[j]=aux;}
}

int i=2; int a=intervale[1].li;


int b=intervale[1].ls;
while(i<=n)
{
if(intervale[i].li>b){cout<<a<<" "<<b<<endl;
a=intervale[i].li; b=intervale[i].ls;
}

if(i==n && intervale[i].li>b)


{
cout<<intervale[i].li<<" "<<intervale[i].ls;
}
i++;
}

}
12. Se considera o multime A cu n numere naturale. Sa se partitioneze in doua submultimi astfel incit
diferenta dintre sumele elementelor componente sa fie minima.
#include<iostream>
using namespace std;
int a[100][100],n;
void citire()
{cin>>n;
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++) {cin>>a[i][j];a[j][i]=a[i][j];}}

void Greedy1()// var 1


{int i,j,ok,culoare[100];
culoare[1]=1;// tara 1 are culoarea 1
for(i=2;i<=n;i++)// pentru fiecare tara i
{j=0;
do
{ j++; ok=0; // cautam prima culoare j care nu a fost utilizata pt colorarea vecinilor k ai lui i
for(int k=1;k<=i-1;k++) if(a[i][k]==1&&culoare[k]==j) ok=1;

} while(ok==1);
culoare[i]=j;// tara i va primi culoarea j
}
for(i=1;i<=n;i++) cout<<"tara="<<i<<" are culoarea="<<culoare[i]<<"\n";
cout<<"\n-------------\n";
}
void Greedy2() // var 2
{int cul=1, tara[20]={0};
for(int i=1;i<=n;i++)
{
for(int k=1;k<=cul;k++)
{
int b=0;
for(int j=1;j<=n;j++)
if(a[i][j]==1 && tara[j]==k) b=1;
if(b==0) tara[i]=k;
}
if(tara[i]==0) tara[i]=++cul;
}
for(int i=1;i<=n;i++) cout<<"tara="<<i<<" are culoarea="<<tara[i]<<'\n';
}
int main()
{citire();Greedy1();Greedy2();}
13. Se doreste colorarea unei harti cu n tari cu cit mai putine culori. Determinati o solutie astfel incit oricare
doua tari vecine sa nu fie colorate cu aceeasi culoare.
14. Un instructor de schi are n perechi de schiuri de lungimi (cm) s1,s2,....sn pe care trebuie sa le
distribuie la n elevi. Acestia au inaltimile (cm) h1,h2,...,hn. El doreste sa distribuie schiurile elevilor
astfel incit suma diferentelor absolute dintre inaltimea elevului si lungimea schiurilor primite de fiecare
sa fie minima. Ajutati-l.
15. Fiind data o tabla de sah nxn si un cal n coltul stnga sus al acesteia, sa se determine o solutie de
parcurgere a tablei de sah astfel nct sa treaca o singura data prin fiecare patrat al tablei. Solutia va fi
afisata:
a. matrice nxn , unde fiecare element va contine numarul sariturii
b. nxn perechi (i,j) , perechea k reprezentind indicele de linie si de coloana de la saritura k.
#include<fstream>
#include<iostream>
#include<iomanip>
using namespace std;
int dx[8]={-1,1,2,2,1,-1,-2,-2};
int dy[8]={-2,-2,-1,1,2,2,1,-1};
int a[201][201],n,ok,k2;
struct traseu{int i,j;} t[100];

ofstream g("cal.txt");

void afis()
{ int i,j;
g<<"n="<<n<<endl;
for(i=1;i<=n;i++)
{ for(j=1;j<=n;j++) g<<setw(4)<<a[i][j]<<" ";
g<<endl;
}
g<<endl;
for(i=1;i<=n*n;i++) g<<'('<<t[i].i<<','<<t[i].j<<')';
//ok=1;
}
int vecin(int i,int j)
{ return (i>=1 && i<=n && j>=1 && j<=n && a[i][j]==0); }

int nr_vecini(int i, int j)//calculeaza in cate pozitii poate merge din i,j
{
int ii,jj,k,x=0;
for(k=0;k<8;k++)
{ ii=i+dx[k];
jj=j+dy[k];
if(vecin(ii,jj) ) x++;
}
return x;
}

void greedy(int i, int j, int k)

{ int k1,v,min=9,i1,j1,ii,jj;
if(!ok)
{
a[i][j]=k;t[++k2].i=i;t[k2].j=j;
if (k==n*n) afis();
else for(k1=0;k1<=7;k1++)
{ ii=i+dx[k1];
jj=j+dy[k1];
if (vecin(ii,jj) )
{
v=nr_vecini(ii,jj);
if(v<min) { min=v; i1=ii; j1=jj;}
}
}
if(min!=9) greedy(i1,j1,k+1);
a[i][j]=0;
}
}

int main()
{ cin>>n;
greedy(1,1,1);
g.close();
return 0;
}

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