0% au considerat acest document util (0 voturi)
96 vizualizări8 pagini

Probleme

Documentul prezintă mai multe probleme de programare rezolvate prin metoda backtracking. Sunt prezentate algoritmi care generează toate permutările unei mulțimi, toate combinațiile de paranteze rotunde corect închise, toate cuvintele formate din vocale, toate numerele formate din cifre impare etc. De asemenea este prezentat un algoritm care descompune un număr într-o sumă de numere prime distincte.

Încărcat de

Stefania Marinescu
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca DOC, PDF, TXT sau citiți online pe Scribd
0% au considerat acest document util (0 voturi)
96 vizualizări8 pagini

Probleme

Documentul prezintă mai multe probleme de programare rezolvate prin metoda backtracking. Sunt prezentate algoritmi care generează toate permutările unei mulțimi, toate combinațiile de paranteze rotunde corect închise, toate cuvintele formate din vocale, toate numerele formate din cifre impare etc. De asemenea este prezentat un algoritm care descompune un număr într-o sumă de numere prime distincte.

Încărcat de

Stefania Marinescu
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca DOC, PDF, TXT sau citiți online pe Scribd

[Link] citeste un numar natural n>=4. Sa se afiseze toate permutarile multimii {1, 2, ...

n}
care au proprietatea ca diferenta absoluta a oricaror 2 elemente alaturate este cel putin
egala cu 2.
Ex: Pentru n=4 se obtin permutarile 2 4 1 3 si 3 1 4 2.
#include<iostream.h>
int x[100],p[100],n;
void afis()
{for(int i=1;i<=n;i++)
cout<<x[i]<<" ";
cout<<endl;
}

int cond(int k)
{ if(k>1) if(x[k]-x[k-1]==1 || x[k]-x[k-1]==-1) return 0;
return 1;
}

void back(int k)
{ for(int i=1;i<=n;i++)
if(!p[i])
{ x[k]=i;
p[i]=1;
if(cond(k)) if(k==n) afis();
else back(k+1);
p[i]=0;
}
}

void main()
{ cin>>n;
back(1);
}

[Link] o tabla de sah nXn sunt plasate m piese marcate prin valoarea -1, iar prin valoarea 0
sunt marcate pozitiile libere. Intr-o pozitie (i0,j0) se afla un cal. Sa se determine traseul
format din numar minim de pasi pe care calul poate sa manance toate piesele de pe tabla
fara a trece de 2 ori prin aceeasi pozitie. Se citesc mai intai n si m, iar apoi m perechi
reprezentand coordonatele pieselor. Ultimele se citesc coordonatele calului. Traseul va fi
marcat intr-o matrice care se va afisa.
#include<fstream.h>
fstream f("[Link]", ios::in);
fstream g("[Link]",ios::out);

int a[100][100],n,io,jo,i1,j1,b[100][3],m;
int min=1000, bsol[100][3], bmat[100][100];
di[8]={-2,-2,-1,1,2,2,1,-1};
dj[8]={-1,1,2,2,1,-1,-2,-2};

int inside(int i,int j)


{ return i>=1 && j>=1 && i<=n && j<=n;
}
void citire()
{ f>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{ f>>a[i][j];
if(a[i][j]==-1) m++;
}
f>>io>>jo;
}

void alege(int k)
{if(k<min)
{ min=k;
int i,j;
for(i=0;i<=min;i++){ bsol[i][1]=b[i][1]; bsol[i][2]=b[i][2];
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
bmat[i][j]=a[i][j];
}
}

void afis()
{ for(int i=1;i<=n;i++)
{ g<<endl;
for(int j=1;j<=n;j++)
g<<bmat[i][j]<<" ";
}
g<<endl;
for(i=0;i<=min; i++)
g<<bsol[i][1]<<","<<bsol[i][2]<<" ";
g<<endl;
}

void back(int i,int j,int k, int l)


{ if(l==m) alege(k-1);
else for(int p=0;p<=7;p++)
{int inou,jnou;
inou=i+di[p];
jnou=j+dj[p];
if(inside(inou,jnou)&& a[inou][jnou]<=0)
{
b[k][1]=inou;
b[k][2]=jnou;
if(a[inou][jnou]==0){ a[inou][jnou]=k+1;
back(inou,jnou,k+1,l);
a[inou][jnou]=0;
}
else{ a[inou][jnou]=k+1;
back(inou,jnou,k+1,l+1);
a[inou][jnou]=-1;
}
}
}
}
void main()
{ citire();
a[io][jo]=1;
b[0][1]=io;
b[0][2]=jo;
back(io,jo,1,0);
afis();
}
[Link] citeste un numar natural n. Sa se afiseze partitiile multimii {1,2,...,n}.
#include<iostream.h>

int n,x[10];

void afis()
{
int i,j,max=0;
max=0;
for(i=1;i<=n;i++)
if(x[i]>max) max=x[i];
for(i=1;i<=max;i++)
{ cout<<"{";
for(j=1;j<=n;j++)
if(x[j]==i) cout<<j<<" ";
cout<<"\b} ";
}
cout<<endl;
}

void back(int k)
{
int i,max;
if(k==n+1) afis();
else
{ max=0;
for(i=1;i<=k-1;i++)
if(x[i]>max) max=x[i];
for(i=1;i<=max+1;i++)
{
x[k]=i;
back(k+1);
}
}
}

int main()
{
cin>>n;
back(1);
return 0;
}
[Link] n>0, natural. Sa se scrie un program care sa afiseze toate partitiile unui numar
natural n.
Numim partitie a unui numar natural nenul n o multime de numere naturale nenule {p1,
p2, …, pk} care îndeplinesc conditia p1+p2+ …+pk = n.
Ex: pt n = 4 programul va afisa:
4 = 1+1+1+1
4 = 1+1+2
4 = 1+3
4 = 2+2
4=4
#include<iostream.h>
int n, ns,sol[20];

void afis(int l)
{ int i;
ns++;
cout<<"Solutia nr. "<< ns<<" : ";
for(i=1;i<=l;i++) cout<<sol[i]<<" ";
cout<<endl;
}

void back(int i, int sp)


{ int j;
if (sp==n) afis(i-1);
else for(j=1;j<=n-sp;j++)
if (j>=sol[i-1])
{
sol[i]=j;
back(i+1, sp+j);
}
}

void main()
{
cin>>n;
ns=0;
back(1,0);
cout<<ns<<" solutii";
}
[Link] citeste de la tastatura un numar natural n par, n<30. Sa se genereze si sa se afiseze pe
ecran toate combinatiile de n paranteze rotunde care se închid corect. De exemplu, pentru
n=4 se obtin urmatoarele combinatii: ( ( ) ) si ( ) ( ) .
#include<iostream.h>

int x[10],n;

void scriesol()
{ int j;
cout<<endl;
for(j=1;j<=n;j++)
if(x[j]==1) cout<<")";
else cout<<"(";
}
int cond(int k)
{ int i,pi=0,pd=0;
for(i=1;i<=k;i++)
if(x[i]==0) pd++;
else pi++;
return pd<=n/2 && pi<=pd;
}
void back(int k)
{
int i;
for(i=0;i<=1;i++)
{
x[k]=i;
if (cond(k))
if (k==n) scriesol();
else back(k+1);
}
}

void main()
{
cin>>n;
back(1);
}
[Link] se scrie un program care genereaza si scrie într-un fisier toate cuvintele formate din
n vocale mici (n numar natural citit de la tastatura, n<10), ordonate alfabetic. De
exemplu, pentru n=3 se vor scrie în fisier:
aaa
aae
aai
aao
aau
aea
.....
uuo
uuu
#include<iostream.h>

int x[10],n;
char v[]="aeiou";

void scriesol()
{ int j;
cout<<endl;
for(j=1;j<=n;j++) cout<<v[x[j]];
}

void back(int k)
{
int i;
for(i=0;i<=4;i++)
{
x[k]=i;
if (k==n) scriesol();
else back(k+1);
}
}

void main()
{
cin>>n;
back(1);
}
[Link] metoda backtracking 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.
#include<fstream.h>

int x[10],n;
long s=0;
ofstream f("[Link]");

void scriesol(int n)
{ int j;
long nr=0;
for(j=1;j<=n;j++)
{ f<<x[j];
nr=nr*10+x[j];
}
s=s+nr;
f<<endl;
}

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

void back(int k, int n)


{
int i;
for(i=1;i<=9;i=i+2)
{
x[k]=i;
if (cond(k))
if (k==n) scriesol(n);
else back(k+1,n);
}
}

void main()
{
for(int i=1;i<=5;i++) back(1,i);
f<<s;
[Link]();
}
Folosind metoda backtracking sa se descompuna in toate modurile un numar natural n ca
suma de numere prime distincte ordonate crescator.
#include<iostream.h>
int n,x[100],v[100],m;
int prim(int n)
{int i;
if(n==0 || n==1) return 0;
else if(n==2 || n==3) return 1;
else if(n%2==0) return 0;
for(i=3;i*i<=n;i+=2)
if(n%i==0) return 0;
return 1;
}
void afis(int n)
{ int i;
for(i=1;i<=n;i++)
cout<<x[i]<<" ";
cout<<endl;
}

void back(int k,int sp)


{ int i;
for(i=1;i<=m;i++)
{ x[k]=v[i];
sp=sp+x[k];
if(sp<=n && x[k]>x[k-1]) if(sp==n) afis(k);
else back(k+1,sp);
sp=sp-x[k];
}

void main()
{ int i;
cin>>n;
m=0;
for(i=2;i<=n;i++) if(prim(i)) { m++;
v[m]=i;
}
back(1,0);
}

sau

#include<iostream>
using namespace std;
int v[50],x[50],n,p;
int prim(int n)
{ if(n==0 || n==1) return 0;
for(int i=2;i<=n/2;i++)
if(n%i==0) return 0;
return 1;
}
void citire()
{ cout<<"n="; cin>>n;
for(int i=1;i<=n;i++) if(prim(i)) v[++p]=i;
}

void afis(int n)
{
for(int i=1;i<=n;i++) cout<<x[i]<<" ";
cout<<endl;
}

void back(int k, int sp)


{
if(sp==n) afis(k-1);
else for(int i=1;i<=p;i++)
{ x[k]=v[i];
if(sp+x[k]<=n && k<=p && x[k]>=x[k-1]+1 || k==1)
back(k+1,sp+x[k]);
}
}

int main()
{ citire();
back(1,0);
return 0;
}

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