Cod sursa(job #887174)

Utilizator ctlin04UAIC.VlasCatalin ctlin04 Data 23 februarie 2013 16:25:35
Problema Zeap Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.64 kb
#include<fstream>
#include<string>
#include<algorithm>
using namespace std;
typedef struct celula{
        int val,h,exr,exl,mindif;
        celula *l, *r;
        celula(){ l=0; r=0; h=1; mindif=1000000000; }
        }*nod;
nod root,st[100];
int i,x,nr;
string s;
bool ok;

int geth(nod n){
    if (n->l==0&&n->r==0) return(1);
     else if (n->r==0) return(n->l->h+1);
      else if (n->l==0) return(n->r->h+1);
       else return(max(n->l->h,n->r->h)+1);
}

int getmindif(nod n){
    if (n->l!=0&&n->r!=0) return(min(min(n->val-n->l->exr,n->r->exl-n->val),min(n->l->mindif,n->r->mindif)));
     else if (n->l==0&&n->r!=0) return(min(n->r->exl-n->val,n->r->mindif));
     else if (n->r==0&&n->l!=0) return(min(n->val-n->l->exr,n->l->mindif));
     else return(1000000000);
}
   
nod rotleft(nod n){
      nod t=n->l;
        n->l=t->r; t->r=n;
       n->h=geth(n);
         t->h=geth(t); 
       if (n->l!=0) n->exl=n->l->exl; else n->exl=n->val;
       if (t->r!=0) t->exr=t->r->exr; else t->exr=t->val;
       n->mindif=getmindif(n);
       t->mindif=getmindif(t);
       
      return(t);
}
 
nod rotright(nod n){
      nod t=n->r;
        n->r=t->l; t->l=n;
       n->h=geth(n);
         t->h=geth(t);
      if (n->r!=0) n->exr=n->r->exr; else n->exr=n->val;
      if (t->l!=0) t->exl=t->l->exl; else t->exl=t->val;
       n->mindif=getmindif(n);
       t->mindif=getmindif(t); 
      
      return(t);
}

nod echilibreaza(nod n){
    n->h=geth(n);
    if ( (n->l!=0 && n->r!=0 && n->l->h>n->r->h+1) || (n->l==0&&n->r!=0&&n->r->h>1) ){
              if (n->l!=0 && n->l->r!=0 && n->l->l!=0 && n->l->r->h>n->l->l->h)
                      n->l=rotright(n->l);
              n=rotright(n);
      }
      else if ( (n->r!=0 && n->l!=0 && n->r->h>n->l->h+1)||(n->r==0&&n->l!=0&&n->l->h>1) ){
                      if (n->r!=0 && n->r->l!=0 && n->r->r!=0 && n->r->l->h>n->r->r->h)
                              n->r=rotleft(n->r);
                      n=rotleft(n);
              }
      else {
           if (n->r!=0) n->exr=n->r->exr; else n->exr=n->val;
           if (n->l!=0) n->exl=n->l->exl; else n->exl=n->val;
           n->mindif=getmindif(n);
           }
      return(n);
}

nod insereaza(nod n, int key){
    if (n==0) { n=new celula; n->val=n->exr=n->exl=key; ++nr; return(n);}
      else if (key>n->val){ nod aux=insereaza(n->r,key); n->r=aux; n->exr=aux->exr;  }
      else if (key<n->val) { nod aux=insereaza(n->l,key); n->l=aux; n->exl=aux->exl; }
    n->mindif=getmindif(n);
    return(echilibreaza(n));
}

nod sterge(nod n, int key){
    if (n==0){ ok=1; return(n);}
    else {
    if (key==n->val){ --nr;
                     if (n->l==0&&n->r==0){ delete(n); return(0); }
                     else if (n->l==0&&n->r!=0) { nod t=n->r; delete(n); return(echilibreaza(t));}
                     else if (n->r==0&&n->l==0) { nod t=n->l; delete(n); return(echilibreaza(t));}
                     else {
                          nod t=n->l, w=t;
                          if (t->r==0) { t->r=n->r; delete(n); return(echilibreaza(t)); }
                          else {
                          while (t->r!=0){ w=t; t=t->r; }
                          w->r=t->l; nod aux=n; t->r=n->r; t->l=n->l; n=t; delete(aux);
                          st[1]=n; st[2]=n->l; t=n->l; int nr=2;
                          while (t->r!=0) {
                                  t=t->r; ++nr; st[nr]=t;
                                  }
                          for (int i=nr; i>=1; --i) st[i]=echilibreaza(st[i]);
                         }}
                     }
    else if (key>n->val) n->r=sterge(n->r,key);
    else n->l=sterge(n->l,key);
  return(echilibreaza(n));}
}

bool cauta(nod n, int key){
     if (n==0) return(0);
     else if (n->val==key) return(1);
     else if (n->val>key) return(cauta(n->l,key));
     else return(cauta(n->r,key));
}                          

int main(void){
    ifstream fin("zeap.in");
    ofstream fout("zeap.out");
    getline(fin,s,char(EOF));
    i=0;
    while (i<s.length()){
     if ((s[i]=='I')||(s[i]=='S')||(s[i]=='C')) {
                    i+=2; x=0; int op=i-2;
                    while (s[i]>'0'&&s[i]<='9'){ x=x*10+int(s[i])-48; ++i; }
                    if (s[op]=='I') root=insereaza(root,x);
                    else if (s[op]=='S') { ok=0; root=sterge(root,x); if (ok) fout<<"-1"<<"\n"; }
                    else fout<<cauta(root,x)<<"\n";
                    }
     else if (s[i+1]=='A'&&nr>=2){ i+=3; fout<<root->exr-root->exl<<"\n"; }
     else if (nr>=2){ i+=3; fout<<root->mindif<<"\n"; }
     else fout<<"-1"<<"\n";
    ++i;
    }
  return(0);
}