Cod sursa(job #1792400)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 30 octombrie 2016 13:46:17
Problema Zeap Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.93 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string.h>
#include <cmath>
#define INF (1 << 30)

using namespace std;

ifstream in("zeap.in");
ofstream out("zeap.out");

struct AVL_Node{
    int info;
    AVL_Node * left, * right;
};

AVL_Node * find(AVL_Node *Root, int key)
{
    if(Root)
    {
        if (key < Root -> info)
            return find(Root -> left, key);
        else
            if(key > Root -> info)
                return find(Root -> right, key);
            else
                return Root;
    }
    return NULL;
}

AVL_Node * LL_Rotation(AVL_Node *Parent)
{
    AVL_Node * temp;
    temp = Parent -> left;
    Parent -> left = temp -> right;
    temp -> right = Parent;
    return temp;
}

AVL_Node * RR_Rotation(AVL_Node *Parent)
{
    AVL_Node * temp;
    temp = Parent -> right;
    Parent -> right = temp -> left;
    temp -> left = Parent;
    return temp;
}

AVL_Node * LR_Rotation(AVL_Node *Parent)
{
    AVL_Node * temp;
    temp = Parent -> left;
    Parent -> left = RR_Rotation(temp);
    return LL_Rotation(Parent);
}

AVL_Node * RL_Rotation(AVL_Node *Parent)
{
    AVL_Node * temp;
    temp = Parent -> right;
    Parent -> right = LL_Rotation(temp);
    return RR_Rotation(Parent);
}

int height(AVL_Node *Root)
{
    int h = 0;
    if(Root)
    {
        int height_left = height(Root -> left);
        int height_right = height(Root -> right);
        h = max(height_left, height_right) + 1;
    }
    return h;
}

int diff(AVL_Node *Root)
{
    if(Root)
    {
        int height_left = height(Root -> left);
        int height_right = height(Root -> right);
        return height_left - height_right;
    }
    return 0;
}

AVL_Node * Balance(AVL_Node *Root)
{
    int dif = diff(Root);
    if (dif < -1)
    {
        if (diff(Root -> right) < 0)
            Root = RR_Rotation(Root);
        else
            Root = RL_Rotation(Root);
    }
    else
        if (dif > 1)
        {
            if(diff(Root -> left) > 0)
                Root = LL_Rotation(Root);
            else
                Root = LR_Rotation(Root);
        }
    return Root;
}

AVL_Node * insert(AVL_Node *Root, int key)
{
    if (Root == NULL)
    {
        Root = new AVL_Node;
        Root -> info = key;
        Root -> left = NULL;
        Root -> right = NULL;
        return Root;
    }
    else
    {
        if (key < Root -> info)
        {
            Root -> left = insert(Root -> left, key);
            Root = Balance(Root);
        }
        else
        {
            Root -> right = insert(Root -> right, key);
            Root = Balance(Root);
        }
    }
    return Root;
}

int ok = 1;

AVL_Node * erase(AVL_Node *Root, int key)
{
    AVL_Node *temp;
    if (Root == NULL)
    {
        ok = -1;
        return Root;
    }
    if (Root -> info == key)
    {
        if (Root -> left == NULL || Root -> right == NULL)
        {
            temp = Root;
            if (Root -> left == NULL)
                temp = Root -> right;
            else
                temp = Root -> left;
            delete Root;
            return temp;
        }
        else
        {
            for (temp = Root -> left; temp -> right; temp = temp -> right);
            Root -> info = temp -> info;
            Root -> left = erase(Root -> left, Root -> info);
            return Balance(Root);
        }
    }
    if (key < Root -> info)
        Root -> left = erase(Root -> left, key);
    else
        Root -> right = erase(Root -> right, key);
    return Balance(Root);
}

int get_min(AVL_Node * Root)
{
    if (Root)
    {
        if (Root -> left == NULL)
            return Root -> info;
        return get_min(Root -> left);
    }
    return -1;
}

int get_max(AVL_Node * Root)
{
    if (Root)
    {
        if (Root -> right == NULL)
            return Root -> info;
        return get_max(Root -> right);
    }
    return -1;
}

int last_val = 0;
int dif = INF;

void inord(AVL_Node * Root)
{
    if (Root)
    {
        if (Root -> left != NULL)
            inord(Root -> left);
        if (last_val == 0)
            last_val = Root -> info;
        else
        {
            if (dif > (int)abs(last_val - Root -> info))
                dif = (int)abs(last_val - Root -> info);
            last_val = Root -> info;
        }
        if (Root -> right != NULL)
            inord(Root -> right);
    }
}

int min_dif(AVL_Node * Root)
{
    if ((Root != NULL) && ((Root -> left != NULL) || (Root -> right != NULL)))
    {
        inord(Root);
        return dif;
    }
    return -1;
}

int max_dif(AVL_Node *Root)
{
    if ((Root != NULL) && ((Root -> left != NULL) || (Root -> right != NULL)))
        return get_max(Root) - get_min(Root);
    return -1;
}

AVL_Node *AVL;
char LINE[20];
unsigned int pos;

void Read(int &x)
{
    pos = 2;
    x = 0;
    unsigned int length = strlen(LINE);
    while(isdigit(LINE[pos]) && pos < length)
    {
        x = x * 10 + (LINE[pos] - '0');
        pos++;
    }
}

int main()
{
    int x;
    while(in.getline(LINE,20))
    {
        if (strchr("ISC",LINE[0]))
        {
            Read(x);
            if (LINE[0] == 'I')
                 AVL = insert(AVL, x);
            else if (LINE[0] == 'C')
                out << (find(AVL, x) ? 1 : 0) << "\n";
            else
            {
                ok = 1;
                AVL = erase(AVL, x);
                if (ok == -1)
                  out << ok << "\n";
            }
            continue;
        }
        if (strcmp(LINE, "MAX") == 0)
        {
            out << max_dif(AVL) << "\n";
            continue;
        }
        if (strcmp(LINE, "MIN") == 0)
        {
            last_val = 0;
            dif = INF;
            out << min_dif(AVL) << "\n";
        }
    }
    in.close();
    out.close();
    return 0;
}