Cod sursa(job #2751107)

Utilizator Andreea__Zavoiu Andreea Andreea__ Data 14 mai 2021 11:21:09
Problema Zeap Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.89 kb
/* Cerinta: un zeap mentine o multime de numere naturale*/ ///distincte => pot folosi set -> elem sunt sortate in ord cresc.
// https://www.geeksforgeeks.org/type-inference-in-c-auto-and-decltype/
#include <iostream>
#include <fstream>
#include <math.h>
#include <set>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("zeap.in");
ofstream fout("zeap.out");

// Using lambda to compare elements. <- https://en.cppreference.com/w/cpp/container/priority_queue
auto cmp = [](pair<int, int> a, pair<int, int> b)
{
    return abs(a.first - a.second) > abs(b.first - b.second);
};

set<int> s; // zeapul
priority_queue< pair<int, int>, vector<pair<int, int> >, decltype(cmp) > pq(cmp); // declared type -> https://en.cppreference.com/w/cpp/container/priority_queue

// Note that by default C++ creates a max-heap for priority queue => ii  putem pune o functie de comparare a elementelor ca sa ni le aranjeze cum vrem noi
// de ex, pt min-heap: priority_queue < int, vector<int>, greater<int> > intre un int si un vector de inturi
// =>
int main()
{
    string tip;

    while(fin >> tip){
        int x;
        if(tip == "I"){
            fin >> x;
            if(s.find(x) == s.end()){
                s.insert(x);
                auto pz = s.find(x); // returns an iterator to the element which is searched in the set container
                if(pz != s.begin()) // daca nu e primul element din set
                {
                    --pz; // vecin stanga
                    pq.push( {*pz, x} ); // tinem in coada de prioritati atat vecinul stanga a lui x (adica iteratorul sau e cel de dinaintea iteratorului lui x) si pe x
                    ++pz; // revenim la iteratorul lui x
                }
                if(pz != s.end()){
                    ++pz; // vecin dreapta
                    if(pz != s.end()){
                        pq.push({x, *pz}); // cat si vecinul dreapta si x
                    }
                }
            }
        }
        else if(tip == "S"){
            fin >> x;
            if(s.find(x) != s.end()){
                auto it = s.find(x); // adresa la care se afla x
                auto it2 = it;
                ++it2; // vecin dreapta
                if(it != s.begin() && it2 != s.end()){
                    --it; // vecin stanga
                    pq.push( {*it, *it2} ); // elimin elementul x deci in pq trb sa elimin iteratorul lui x adica sa ii fac vecini pe iteratorul sau din stanga si pe cel din dreapta
                }
                s.erase(x);
            }
            else fout << -1 << '\n';
        }
        else if(tip == "C"){
            fin >> x;
            fout << (s.find(x) != s.end()) << '\n'; // afiseaza 1 sau 0 adica l-a gasit pe x in container sau nu
        }
        else if(tip == "MAX"){
            if(s.size() < 2) // daca nu am minim 2 elemente intre care sa pot face diferenta, returnez -1
                fout << -1 << '\n';
            else {
                auto it = s.end(); // iteratorul de la sfarsit
                --it; // iteratorul pentru ultimul element din container
                fout << *it - *s.begin() << '\n'; // diferenta maxima e ultimul elem - primul, pt ca in set sunt tinute in ordine crescatoare
            }
        }
        else {  // "MIN"
            if(s.size() < 2)
                fout << -1 << '\n';
            else{
                while(s.find(pq.top().first) == s.end() || s.find(pq.top().second) == s.end()) // scot din varful cozii (adica dintre diferentele cele mai mici, care ma intereseaza pe mine)
                    pq.pop();                                                                 // acele perechi din care unul din elemente a fost sters
                fout << abs(pq.top().first - pq.top().second) << '\n'; // raman in varf cu diferenta minima potrivita, pe care o afisez
            }
        }
    }

}