Cod sursa(job #711485)

Utilizator DraStiKDragos Oprica DraStiK Data 12 martie 2012 11:19:02
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
//Oprica Dragos Vasile
//FMI Unibuc - Grupa 135
//Hahuri - 100p pe infoarena
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <ctime>
using namespace std;

#define OFFSET 1.25
#define DEL -1
#define NIL 0

int get_prime (int N) { // returneaza primul numar prim <= N
  bool *tmp;
  int i,j,prime;

  tmp=new bool[N+1];
  for (i=0; i<=N; ++i)
    tmp[i]=0;

  prime=2;
  for (i=2; i<=N; ++i)
    if (!tmp[i]) {
      prime=i;

      for (j=i; j<=N; j+=i)
        tmp[j]=1;
    }
  delete[] tmp;

  return prime;
}

class hash_table {

  int hash_size; // Dimensiunea hash-ului
  int *T;        // tabela hashului

  int h1 (int key) {  //prima functie de hash: h(x) = x % M, unde M este un numar prim

    return key%this->hash_size;
  }

  int h2 (int key) { // a doua functie de hash: h(x) = 1+ x % M', unde M' este un numar mai mic decat M, de exemplu M-1

    return 1+key%(this->hash_size-1);
  }

  int h (int key,int poz) { // folosim double hashing pentru a elimina coliziunile
                            // a doua functie de hash trebuie sa fie un numar pozitiv mai mic strict decat M, pentru ca
    return (this->h1 (key)+poz*this->h2 (key))%this->hash_size; // functia de hashing sa functioneze corect
  }

  public:
  hash_table (int hash_size) { // contructorul clasei, pentru numarul operatiilor dat si vom folosi un numar prim
                               // mai mare decat dimensiunea data ca dimensiune a tabelei
    this->hash_size=get_prime ((int)(OFFSET*hash_size));
    this->T=new int[this->hash_size];
  }

  int find (int key) { // cauta o cheie x, daca o gaseste returneaza pozitia ei din tabela hash, altfel -1
    int i,j;

    for (i=0; i<this->hash_size; ++i) {

        j=this->h (key,i);
        if (this->T[j]==key)
          return j;

        if (this->T[j]==NIL)
          return -1;
    }

    return -1;
  }

  void insert (int key) { // insereaza o cheie x, daca aceasta nu exista deja in tabela hash
    int i,j,is;

    is=this->find (key);
    if (is!=-1)
      return ;

    for (i=0; i<this->hash_size; ++i) {

      j=this->h (key,i);
      if (this->T[j]==NIL || this->T[j]==DEL) {

        this->T[j]=key;
        return ;
      }
    }
  }

  void erase (int key) { // sterge o cheie x, marcand-o in tabea hash ca fiind o valoare stearsa
    int is;              // ce poate fi utilizata ulterior

    is=this->find (key);
    if (is==-1)
      return ;

    this->T[is]=DEL;
  }
};

int main () {
  srand (time (NULL));
  assert (freopen ("hashuri.in","r",stdin));
  assert (freopen ("hashuri.out","w",stdout));

  int T,i,x,tip;

  assert (scanf ("%d",&T));
  hash_table Hash (T);
  for (i=1; i<=T; ++i) {

    assert (scanf ("%d%d",&tip,&x));

    if (tip==1)
        Hash.insert (x);

    if (tip==2)
        Hash.erase (x);

    if (tip==3) {

      if (Hash.find (x))
        printf ("1\n");
      else
        printf ("0\n");
    }
  }

  return 0;
}