#include <iostream>
#include <cmath>//Pentru functia sqrt
using namespace std;
int n, x, mini;
//Memorarea listei:
struct nod
{
int info;
nod* urm;
};
nod* p = NULL;//Declararea listei vida
void adaugarefinal(nod*& p, int x)
{
//Initializam noul nod si ii atribuim valoarea din parametrul x
nod* q = new nod;
q->info = x;
q->urm = NULL;
if (p == NULL)//Daca lista e vida, punem elementul in lista
p = q;
else
{
nod* t = p;
while (t->urm)//Parcurgem lista pana la capat
t = t->urm;
t->urm = q;//Ultimul element devine elementul creat anterior
}
}
void afisare(nod* p)
{
while (p)
{
cout << p->info << " ";//Afisam numarul curent
p = p->urm;//Ne mutam la urmatorul element, cat timp avem elemente
}
}
int exista_pp(nod* p)//Verificam daca avem cel putin un element de tip pp altfel afisam un mesaj la apelul functiei
{
while (p)
{
if (sqrt(p->info) == (int)sqrt(p->info))// (int)sqrt reprezinta numarul scris cu zecimale; in cazul in care nu are zecimale:
return 1;//Returnam valoarea 1 imediat dupa gasirea unei prime valori, astfel intrerupem parcurgerea
p = p->urm;
}
return 0;//Returnam 0 in cazul in care nu avem niciun numar de tip pp
}
void afisare_pp(nod* p)//Afisam numerele care sunt de tip pp daca functia de mai sus are valoarea 1
{
while (p)//Parcurgem lista pana la final
{
if (sqrt(p->info) == (int)sqrt(p->info))
cout << p->info << " ";//Afisam numerele de tip pp
p = p->urm;
}
}
int nr_prime(nod* p)//Determinam cate numere prime avem,in caz contrar afisam mesaj
{
int k = 0, ok;
while (p)//Parcurgem lista pana la final
{
ok = 1;
if (p->info < 2)
ok = 0;
else
if (p->info == 2 || p->info == 3)
ok = 1;
else
{
for (int i = 2; i <= p->info / 2; i++)//Luam divizori pana la jumatatea numarului
if (p->info % i == 0)//In cazul in care se imparte exact , nu avem numar prim
{
ok = 0;
break;
}
}
if (ok)//In cazul in care este satisfacuta conditia , contorizam +1 la contorul k
k++;
p = p->urm;
}
return k;//Numarul de elemente prime
}
int ordine(nod* p)
{
while (p->urm)//Verificam elemente consecutive, doua cate doua , astfel ne asiguram ca elementul urmator nu e null
{
if (p->info < p->urm->info)//Daca o singura pereche de elemente consecutive nu indeplineste conditia, intrerupem parcurgerea
return 0;
p = p->urm;
}
return 1;
}
int nr_mini(nod* p)
{
int i = 0;//Contor pentru numarul de aparitii a valorii mini
while (p)//Parcurgem lista pana la final
{
if (p->info == mini)//Daca elementul curent este egal cu mini, contorizam +1 la contorul i
i++;
p = p->urm;
}
return i;
}
void inserare_elem(nod* p, nod* q, int x)//Inseram un element, imediat dupa un element cunoscut
{
nod* nou = new nod;
nou->info = x;
nou->urm = q->urm;
q->urm = nou;
}
void dublare(nod* p)
{
nod* t = p;
while (t)//Parcurgem lista pana la final
{
//Determinam suma cifrelor valorii curente din lista prin intermediul unei variabile s si a unei copii a elementului curent
int s = 0;
int copie = t->info;
while (copie)
{
s += copie % 10;
copie /= 10;
}
if (s < 15)
{
inserare_elem(p, t, t->info);//Apel la functia de inserare pt a adauga in lista elementul care satisface conditia
t = t->urm;//Acest t->urm executat aici cat si mai in fata,ne ajuta sa sarim peste valoarea deja introdusa pt a nu executa la nesfarsit
}//Intrucat primul t->urm ajunge la valoarea deja introdusa, urmatorul are rolul de a sari peste el
t = t->urm;//Daca t->urm-ul anterior nu are loc, secventa doar trece la urmatorul element
}
}
int main()
{
int ok = 1;
cin >> n;//Numarul de elemente din lista
//Citire lista
for (int i = 1; i <= n; i++)
{
cin >> x;
adaugarefinal(p, x);//Adaugarea unui element in lista
//Determinarea valorii minime din lista
if (ok == 1)//Secventa care se parcurge o singura data pentru a determina un minim initial
{
mini = x;
ok = 0;
}
if (x < mini)
mini = x;
}
//a.Afisare lista:
cout << "Afisare lista: ";
afisare(p);
cout << endl;
//b.Determinare pp:
if (exista_pp(p) == 1)
{
cout << "Numere pp: ";
afisare_pp(p);
cout << endl;
}
else
cout << "Nu exista pp." << endl;
//c.Afisare nr prime:
if (nr_prime(p) == 0)
cout << "Nu exista nr prime." << endl;
else
cout << "Numere prime in total: " << nr_prime(p) << endl;
//d.Ordinea listei:
if (ordine(p))
cout << "Lista este ordonata descrescator." << endl;
else
cout << "Lista nu este ordonata descrescator." << endl;
//e.Nr aparitii val mini:
if (nr_mini(p) >= 2)
cout << "Numarul minim: " << mini << " apare de " << nr_mini(p) << " ori." << endl;
else if (nr_mini(p) == 1)
cout << "Numarul minim: " << mini << " apare o singura data." << endl;
//f.Dublare elemente(sum_cif<15):
dublare(p);
cout << "Afisare duble: ";
afisare(p);
return 0;
}