Pagini recente » Cod sursa (job #2783500) | Cod sursa (job #578866) | Cod sursa (job #1908906) | Cod sursa (job #2395776) | Cod sursa (job #2749995)
#include <fstream>
#include <iostream>
#include <set>
#include <queue>
#include <string>
using namespace std;
ifstream fin ("zeap.in");
ofstream fout ("zeap.out");
struct pereche //strucutra ce retine doua elemente vecine din zeap
{
int st,dr;
pereche(){}
pereche(int x, int y)
{
st = x;
dr = y;
}
};
class cmp //clasa de comparator pentru priority queue
{
public:
bool operator () (const pereche& a, const pereche& b) //supraincarc operatorul () pentru a compara doua perechi
{
return abs(a.st - a.dr) > abs(b.st - b.dr); //compar diferentele dintre elementele perechilor
}
};
priority_queue<pereche, vector<pereche>, cmp> PQ; //priority queue se va implementa printr-un vector de perechi,
// utilizand comparatorul cmp
//functia de inserare a unui element in zeap-ul Z
//care insereaz un element daca acesta nu exista deja in zeap si intoarce 1,
//iar in caz contrat intoarce -1
int insereaza(set<int> &Z,int x)
{
if(!Z.count(x)) //testez daca Z nu il contine deja pe x
{
Z.insert(x); //daca nu il contine deja, il adaug
return 1;
}
else return -1;
}
//functia de stergere a unui element din zeap-ul Z(functia va returna 1 daca stergerea a reusit si -1 in caz contrat,
// adica daca x nu se afla in Z)
int sterge(set<int> &Z,int x)
{
if(!Z.count(x)) //testez daca Z nu il contine pe x
return -1;
else //daca sterg elementul, inainte de stergere aflu pozitia sa, il elimin si apoi fac pereceh intre
//vecinul sau din stanga si vecinul sau din dreapta
{
//it1 = vecin din stanga, it2 = vecin din dreapta
set<int>::iterator it1 = Z.find(x);
set<int>::iterator it2 = it1;
++it2;
if(it1 != Z.begin() && it2 != Z.end()) //verific daca am ambii vecini
{
--it1; //scad it1 dupa verificare, deoarece pozitia lui x poate fi chiar Z.begin()+1
PQ.push(pereche(*it1, *it2));
}
Z.erase(x);
return 1;
}
}
//functie care cauta elementul x in zeap-ul Z si returneaza 0 daca elementul nu exista si 1 daca exista
int cauta(set<int> &Z,int x)
{
if(Z.count(x))
return 1;
else
return 0;
}
//functie care returneaza diferenta in modul maxima dintre oricare doua elemente distincte din zeap-ul Z;
//daca nu exista cel putin doua elemente in zeap se returneaza -1;
int max_dif(set<int> &Z)
{
//set-ul este implementat cu un arbore binar de cautare, asta inseamna ca primul element este cel mai mic,
//iar ultimul element este cel mai mare(set-ul este ordonat)
if(Z.size() < 2) //am cel mult un element, deci nu pot avea diferenta dintre 2 numere distincte
return -1;
else
{
set<int>::iterator prim = Z.begin(), ultim = Z.end();
--ultim; //deoarece Z.end() intoarce prima adresa din afara setului
return *ultim - *prim;
}
}
//functie care returneaza diferenta in modul minima dintre oricare doua elemente distincte din zeap-ul Z;
//daca nu exista cel putin doua elemente in zeap se returneaza -1;
int min_dif(set<int> &Z)
{
if(Z.size() < 2) //am cel mult un element, deci nu pot avea diferenta dintre 2 numere distincte
return -1;
else
{
//cat timp perechea din varful cozii cu prioritati(perechea cu diferenta minima) este incompleta
while(!Z.count(PQ.top().st) ||!Z.count(PQ.top().dr))
{
PQ.pop();
}
return abs(PQ.top().st - PQ.top().dr);
}
}
int main()
{
set<int> Z;
string s;
int x;
while(fin >> s)
{
if(s == "I")
{
fin >> x;
int rez = insereaza(Z, x);
if(rez == 1) //daca am inserat elementul nou
{
set<int>::iterator it = Z.find(x); //aflu pozitia din zeap unde a fost inserat
//apoi fac perechile dintre elementul curent si vecinii sai
if(it != Z.begin())
{
set<int>::iterator it2 = it; //vecinul din stanga
--it2;
PQ.push(pereche(*it2, x)); //pun perechea formata in PQ
}
set<int>::iterator it3 = it; //vecinul din dreapta
++it3;
if(it3 != Z.end())
{
PQ.push(pereche(x, *it3)); //pun perechea formata in PQ
}
}
}
else if(s == "S")
{
fin >> x;
int rez = sterge(Z, x) ;
if(rez == -1)
fout << "-1\n";
}
else if(s == "C")
{
fin >> x;
fout << cauta(Z, x) << "\n";
}
else if(s == "MIN")
{
fout << min_dif(Z) << "\n";
}
else
{
fout << max_dif(Z) << "\n";
}
}
return 0;
}