Pagini recente » Cod sursa (job #2890582) | Cod sursa (job #2942036) | Cod sursa (job #204947) | Cod sursa (job #144159) | Cod sursa (job #2899311)
#include <string.h>
#include <fstream>
#include <set>
#include <queue>
#include <string>
#include <iterator>
using namespace std;
ifstream fin("zeap.in");
ofstream fout("zeap.out");
string input;
set<int> zeap;
/*
* Setul are elementele ordonate crescator => pentru diferent minima trebuie doar sa calculez
* diferentele dintre elementele consectutive, iar pentru diferenta maxima voi
* face diferenta dintre primul si ultimul element
*
* Pentru a retine diferentele minime voi folosi un priority queue in care tin minte
* o pereche formata din diferenta (pe care o pun cu minus ca sa am un min heap)
* si perechea formata din elementul si cel mai apropiat cu care fac diferenta
*/
priority_queue<pair<int, pair<int, int>>> min_dif; // "sortarea" se face dupa primul element din tuplu, cel mai mare avand prioritate maxima
// deci ca sa il fac de minim trebuie sa pun toate valorile cu minus
int numar (string x)
{
int nr = 0;
for (int i = 2; i < x.size(); i++)
{
nr = nr * 10 + (x[i] - '0');
}
return nr;
}
void insereaza (int x)
{
if (zeap.find(x) == zeap.end()) // Daca numarul nu este deja in zeap
{
// Inseram numarul:
zeap.insert(x);
//Daca zeapul contine mai mult de 2 elemente pentru a face diferentele minime, le si calculez
if (zeap.size() >= 2)
{
// Verificam daca zeapul are mai mult de doua elemente ca sa putem sa facem diferentele dintre
// x si elementele de langa el
/*
* Daca sunt mai mult de 2 elemente in zeap, o sa calulez diferenta dintre
* noul element x si cele mai apropiate 2 elemente si le inserez in priority queue.
*
* Voi gasi cele mai apropiate doua elemente folosind un obiect de tip iterator, declarand o var
* de tip auto pentru a lasa compilatorul sa determine ca este un iterator
* (imi este lene sa scriu set<int>::iterator i;), iar apoi il folosesc ca sa pargurg multimea
*
* Astfel parcurg mutimea prin acest iterator si determin elemtemtul de dinaintea si de dupa x
*/
auto i = zeap.find(x);
if (i != zeap.begin())
{
i--; // Iau elementul din stanga sa
min_dif.push(make_pair(-abs(*i - x), make_pair(*i,
x))); // Bag in queue diferenta urmata de numerele care au dat diferenta
}
// Fac acelasi lucru si pentru elementele din dreapta (vad daca x nu este ultimul si fac diferenta)
i = zeap.find(x);
i++;
if (i != zeap.end())
{
min_dif.push(make_pair(-abs(*i - x), make_pair(*i, x)));
}
}
}
}
void sterge (int x)
{
if (zeap.find(x) == zeap.end())
{
fout << "-1\n";
return;
}
auto i = zeap.find(x);
auto right = i;
right++;
// Daca este primul sau ultimul element il sterg fara sa imi fac griji ca afectez vreo diferenta
if (i == zeap.begin() || right == zeap.end()) // (1)
zeap.erase(x);
else
{
// Gasim si elementul din stanga pentru ca stim ca x nu este primul element
auto left = i;
left--;
// Daca nu este primul element si nici ultimul (nu ne putem baza pe (1) pentru ca este sau intre conditii)
if (i != zeap.begin() && right != zeap.end())
{
// Trebuie sa introducem diferenta dintre elementul din dreapta si cel din stanga lui x,
// pentru ca acum ele ajung unul langa altul
min_dif.push(make_pair(-abs(*right - *left), make_pair(*left, *right)));;
}
zeap.erase(x);
}
}
void cauta (int x)
{
if (zeap.find(x) == zeap.end())
{
fout << "0\n";
return;
}
fout << "1\n";
}
void minim()
{
if(zeap.size() < 2)
{
fout << "-1\n";
return;
}
// Trebuie sa scoatem toate diferentele dintre 2 elemente consecutive dintre care unul sau ambele
// nu mai sunt in multime pentru a gasi prima diferenta valida (care este si cea mai mica)
while(zeap.find(min_dif.top().second.first) == zeap.end()
|| zeap.find(min_dif.top().second.second) == zeap.end())
min_dif.pop();
fout << -min_dif.top().first << '\n';
}
void maxim()
{
if(zeap.size() < 2)
{
fout << "-1\n";
return;
}
auto left = zeap.begin();
auto right = zeap.end();
right--;
fout << *right - *left << '\n';
}
int main ()
{
int x;
while (getline(fin, input))
{
if (input[0] == 'I')
{
x = numar(input); // Aici creem numarul care trebuie inserat
insereaza(x);
} else if (input[0] == 'S')
{
x = numar(input);
sterge(x);
} else if (input[0] == 'C')
{
x = numar(input);
cauta(x);
} else if(input == "MAX")
{
minim();
} else if(input == "MIN")
{
maxim();
}
}
return 0;
}