Sunteți pe pagina 1din 12

VASILE OCTAVIAN 11A

TEMĂ INFORMATICĂ
4 PROBLEME

PROBLEMA 1 -divide et impera-


Se citesc doua numere, n si x, n natural si x real pozitiv. Fara a folosi functia
pow, extrageti cu 3 zecimale exacte radicalul de ordinul n din x.
REZOLVAREA PROBLEMEI
#include<iostream>
#include<cmath>

using namespace std;

float f(float y, int n, float x)


{
float p=1;
for(int i=1;i<=n;i++) p=p*y;
return p-x;
}

float DEI(float s, float d, int n, float x)


{
if(d-s<=0.0001) return s;
else
{ float m=(s+d)/2;
if(f(m,n,x)==0) return m;
else if(f(m,n,x)<0) return DEI(m,d,n,x);
else return DEI(s,m,n,x);
}
}

int main()
{
int n;
float x;
cin>>n>>x;
cout<<DEI(0,sqrt(x),n,x);
return 0;
}

EXPLICAREA PROBLEMEI
Problema prezentată este un program în limbajul C++ care implementează metoda de căutare
a rădăcinii unei funcții utilizând metoda de diviziune a intervalului (metoda bisecției).
Bibliotecile „iostream”și „cmath”sunt incluse pentru a permite citirea/afișarea datelor și
pentru a utiliza funcțiile matematice, cum ar fi „sqrt()”.
Funcția „f()” primește trei parametri: „y” (un număr real), „n”(un întreg) și „x” (un număr
real). Această funcție calculează rezultatul expresiei „y^n – x” și îl returnează.
VASILE OCTAVIAN 11A
Funcția „DEI()” primește patru parametri: „s” și „d” (ambele numere reale) reprezentând
limitele intervalului în care căutăm rădăcina, „n” (un întreg) și „x” (un număr real). Această
funcție implementează metoda de diviziune a intervalului pentru a căuta rădăcina ecuației
„f(y,n,x) = 0” în intervalul [s, d].
Dacă diferența dintre „d” și „s” este mai mică sau egală cu 0.0001 (un prag de eroare ales),
funcția returnează „s” ca aproximare a rădăcinii.
În caz contrar, funcția calculează mijlocul intervalului și verifică valoarea funcției „f()” în
acest punct.
Dacă funcția este exact zero, se consideră că mijlocul intervalului este rădăcina și se
returnează.
Dacă funcția este negativă în mijlocul intervalului, se reapelează recursiv funcția „DEI()” pe
intervalul din mijlocul intervalului până la „d”.
Dacă funcția este pozitivă în mijlocul intervalului, se reapelează recursiv funcția „DEI()” pe
intervalul de la „s” până la mijlocul intervalului.
În funcția „main()”, se declară variabilele „n” (un întreg) și „x” (un număr real). Acestea sunt
citite de la tastatură.
Se apelează funcția „DEI()” cu valorile 0 și radicalul lui „x” (calculat cu „sqrt(x)”) ca limite
de interval, „n” și „x” ca parametri.
Rezultatul returnat de „DEI()” este afișat utilizând „cout”.
Astfel, programul calculează și afișează o aproximare a rădăcinii ecuației „f(y,n,x) = 0”
folosind metoda bisecției pe intervalul [0, sqrt(x)].
VASILE OCTAVIAN 11A

PROBLEMA 2 -divide et impera-


Se citeste un numar real x. Sa se calculeze radical de ordinul 3 din x folosind
un algoritm de tip Divide et impera.
REZOLVAREA PROBLEMEI
#include<iostream>
using namespace std;
double r3(double x, double s, double d)
{
if(d-s<=0.0001) return d;
else
{ double m=(s+d)/2;
if(m*m*m<x) return r3(x,m,d);
else return r3(x,s,m);
}
}

int main()
{ double x;
cin>>x;
if(x>0) if(x<1) cout<<r3(x,0,1);
else cout<<r3(x,0,x);
else if(x>-1) cout<<r3(x,-1,0);
else cout<<r3(x,x,0);
system("pause");
return 0;
}
VASILE OCTAVIAN 11A

EXPLICAREA PROBLEMEI
Problema prezentată este un program în limbajul C++ care calculează aproximarea cubului
unei valori date folosind metoda de diviziune a intervalului (metoda bisecției).
Biblioteca „iostream” este inclusă pentru a permite citirea/afișarea datelor.
Funcția „r3()” primește trei parametri: „x” (un număr real) reprezentând valoarea căreia i se
calculează cubul, „s” și „d” (ambele numere reale) reprezentând limitele intervalului în care
căutăm aproximarea cubului.
Dacă diferența dintre „d” și „s” este mai mică sau egală cu 0.0001 (un prag de eroare ales),
funcția returnează „d” ca aproximare a cubului lui „x”.
În caz contrar, funcția calculează mijlocul intervalului și verifică dacă cubul mijlocului este
mai mic sau mai mare decât „x”.
Dacă cubul mijlocului este mai mic decât „x”, se reapelează recursiv funcția „r3()” pe
intervalul din mijlocul intervalului până la „d”.
Dacă cubul mijlocului este mai mare sau egal cu „x”, se reapelează recursiv funcția „r3()” pe
intervalul de la „s” până la mijlocul intervalului.
În funcția „main()”, se declară variabila „x” (un număr real) care reprezintă valoarea pentru
care se dorește calcularea aproximării cubului. Aceasta este citită de la tastatură.
Se efectuează o serie de verificări condiționale pentru a decide intervalul inițial pentru apelul
funcției „r3()”.
Dacă „x” este mai mare decât 0 și mai mic decât 1, se apelează „r3()” pe intervalul [0, 1].
Dacă „x” este mai mare sau egal cu 1, se apelează „r3()” pe intervalul [0, x].
Dacă „x” este mai mic decât 0 și mai mare sau egal cu -1, se apelează „r3()” pe intervalul [-1,
0].
Dacă „x” este mai mic decât -1, se apelează „r3()” pe intervalul [x, 0].
Rezultatul returnat de „r3()” este afișat utilizând „cout”.
La sfârșit, se utilizează funcția „system("pause")” pentru a opri executarea programului
înainte de închiderea acestuia.
Astfel, programul calculează și afișează o aproximare a cubului valorii „x” folosind metoda
bisecției pe intervalul corespunzător în funcție de valoarea lui „x”.
VASILE OCTAVIAN 11A

PROBLEMA 3 -divide et impera-


Se citeste un vector cu n elemente numere naturale. Sa se determine
elementul minim din vector folosind divide et impera.
REZOLVAREA PROBLEMEI
#include<iostream>

using namespace std;

int min(int a[100],int s , int d)


{
if ( s == d ) return a[s];
else
{
int m = (s+d)/2;
int m1 = min(a,s,m);
int m2 = min(a,m+1,d);

if ( m1 < m2 ) return m1;


else return m2;

}
}

int main()
{
int a[100];
int n ;
cin>> n;
for (int i = 0 ; i < n ;i++)
cin>>a[i];
VASILE OCTAVIAN 11A

cout << min(a,0,n-1);

return 0;
}

EXPLICAREA PROBLEMEI
Problema prezentată este un program în limbajul C++ care determină elementul minim dintr-
un vector de numere întregi utilizând o abordare recursivă.
Biblioteca „iostream” este inclusă pentru a permite citirea/afișarea datelor.
Funcția „min()” primește trei parametri: „a” (un vector de numere întregi), „s” și „d” (ambele
numere întregi) reprezentând limitele intervalului în care căutăm elementul minim.
Dacă „s” și „d” reprezintă aceeași poziție în vector (au aceeași valoare), înseamnă că am ajuns
la o singură valoare în interval și returnăm această valoare din vector.
În caz contrar, funcția calculează mijlocul intervalului și apelează recursiv funcția „min()” pe
două subintervaluri: [s, m] și [m+1, d], unde „m” este mijlocul intervalului.
Rezultatele apelurilor recursive sunt stocate în variabilele „m1” și „m2”.
Se compară valorile „m1” și „m2” și se returnează minimul dintre ele.
În funcția „main()”, se declară vectorul „a” de numere întregi și variabila „n” (un număr
întreg) care reprezintă lungimea vectorului. Aceasta este citită de la tastatură.
Se citesc elementele vectorului „a” utilizând o buclă „for” care se execută de la 0 la „n-1”.
Se apelează funcția „min()” cu vectorul „a”, și limitele 0 și „n-1”.
Rezultatul returnat de „min()” (elementul minim din vector) este afișat utilizând „cout”.
La sfârșit, se returnează 0 pentru a indica încheierea programului.
Astfel, programul determină și afișează elementul minim dintr-un vector de numere întregi
utilizând o abordare recursivă și divizarea intervalului.
VASILE OCTAVIAN 11A

PROBLEMA 4 -backtracking-
Se citeste un cuvant format din maxim 10 litere mici distincte. Afisati in
ordine lexicografica toate anagramele cuvantului citit care au proprietatea
ca nu contin doua vocale alaturate si nici doua consoane alaturate (practic
vocalele si consoanele trebuie sa alterneze).
Daca acest lucru nu este posibil se va afisa mesajul IMPOSIBIL.
Exemplu:
Daca s="cosmina"
VASILE OCTAVIAN 11A

anagramele vor fi:


caminos
camison
camonis
...
sonimac
Daca s="cosmin" se va afisa IMPOSIBIL
REZOLVAREA PROBLEMEI
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int n,X[12],P[12];
char s[12];

void afisare()
{
for(int i=1;i<=n;i++)
cout<<s[X[i]-1];
cout<<endl;
}

int valid(int k)
{
if(k>1) //daca sunt cel putin la cea de-a doua litera
{
if(strchr("aeiou",s[X[k]-1])==0 &&
strchr("aeiou",s[X[k-1]-1])==0)
return 0; //doua consoane alaturare => 0
if(strchr("aeiou",s[X[k]-1])!=0 &&
strchr("aeiou",s[X[k-1]-1])!=0)
return 0; //doua vocale alaturate => 0
}
return 1;
}

void back(int k)
{
for(int i=1;i<=n;i++)
if(!P[i])
{
P[i]=1;
X[k]=i;
if(valid(k))
if(k==n) afisare();
else back(k+1);
P[i]=0;
}
}

void ordonare(char s[])


{
int l=strlen(s);
for(int i=0;i<l;i++)
for(int j=i+1;j<l;j++)
VASILE OCTAVIAN 11A
if(s[i]>s[j])
{
char aux=s[i];
s[i]=s[j];
s[j]=aux;
}
}

int main()
{
cin>>s;
n=strlen(s);
int cv=0,cc=0;
for(int i=0;i<n;i++)
if(strchr("aeiou",s[i])==0) cc++;//numaram consoanele
else cv++;//numaram vocalele
if(abs(cc-cv)>1) cout<<"IMPOSIBIL";//diferenta>1 => imposibil
else
{
ordonare(s);//ordonez alfabetic cuvantul
back(1);
}
return 0;
}

EXPLICAREA PROBLEMEI
Această problemă este un program în limbajul C++ care generează și afișează toate
permutările unui cuvânt dat, cu următoarele restricții:
Cuvântul trebuie să aibă cel mult 12 caractere.
În fiecare permutare generată, nu pot exista două consoane sau două vocale consecutive.
Bibliotecile „iostream”, „cstring” și „cstdlib” sunt incluse pentru a permite citirea/afișarea
datelor și pentru a utiliza funcții pentru lucrul cu șirurile de caractere și operații matematice.
Variabilele globale „n”, „X[12]”, „P[12]” și „s[12]” sunt declarate pentru a stoca informațiile
necesare în cadrul programului. „n” reprezintă lungimea cuvântului, „X” și „P” sunt utilizate
pentru generarea permutărilor, iar „s” stochează cuvântul citit.
Funcția „afisare()” afișează o permutare a cuvântului. Se parcurge vectorul „X[]”, care
conține indicii caracterelor în permutare, și se afișează caracterele corespunzătoare din șirul
de caractere „s[]”.
Funcția „valid(int k)” verifică dacă o anumită permutare este validă. Verificările se fac astfel:
Dacă „k” este mai mare decât 1 (adică suntem la cel puțin a doua literă în permutare), se
verifică dacă două consoane consecutive sau două vocale consecutive există în cuvântul
original.
Dacă există două consoane consecutive sau două vocale consecutive, se returnează 0 pentru a
indica invaliditatea permutării.
În caz contrar, se returnează 1 pentru a indica că permutarea este validă.
VASILE OCTAVIAN 11A
Funcția „back(int k)” implementează algoritmul de generare a permutărilor utilizând tehnica
de backtracking. Algoritmul este recursiv și parcurge toate opțiunile posibile pentru fiecare
poziție în permutare.
Pentru fiecare valoare posibilă a „X[k]”, care reprezintă indicele unei litere din cuvânt, se
verifică dacă acea valoare a fost deja utilizată („P[i]=1”). Dacă nu a fost utilizată, se atribuie
valoarea „X[k]” și se verifică dacă permutarea este validă utilizând funcția „valid(k)”.
Dacă permutarea este validă, se verifică dacă am ajuns la ultima poziție („k == n”). Dacă da,
se apelează funcția „afisare()” pentru a afișa permutarea.
În caz contrar, se apelează recursiv funcția „back(k+1)” pentru a continua generarea
permutărilor.
Funcția „ordonare(char s[])” sortează șirul de caractere „s[]” în ordine alfabetică. Se utilizează
un algoritm simplu de sortare prin interschimbare a caracterelor.
În funcția „main()”, se citește cuvântul de la intrare utilizând „cin>>s;”. Se determină
lungimea cuvântului și se numără consoanele și vocalele din cuvânt.
Dacă diferența absolută dintre numărul de consoane și numărul de vocale este mai mare decât
1, se afișează mesajul "IMPOSIBIL", deoarece nu este posibil să se respecte regulile
permutărilor.
În caz contrar, se ordonează cuvântul în ordine alfabetică utilizând funcția „ordonare(s)”.
Apoi, se apelează funcția „back(1)” pentru a începe generarea permutărilor și afișarea
acestora.
Această implementare utilizează backtracking pentru a genera permutările și verifică regulile
de validitate pentru a afișa doar permutările corecte.
VASILE OCTAVIAN 11A
VASILE OCTAVIAN 11A

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