Cod sursa(job #708652)

Utilizator Marius_mFMI-M2 Marius Melemciuc Marius_m Data 7 martie 2012 00:48:50
Problema Hashuri Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include<stdio.h>
#include<iostream>
#include<math.h>
#define subunitar 0.618                                                  // aproximarea numarului sugerat de Donald Knuth
#define m 262144                                                // pow(2,18)
#define POSITIVE(a)  (a>=0) ? a : a+m

using namespace std;

typedef struct nod {int info;
					nod *back,*next;}NOD;

inline int hash(int x)                                                              // functie hash bazata pe metoda inmultirii
{
	int position=(int)( m * ( x*subunitar-(int)(x*subunitar) ) );
	//return position>=0 ? position : position+prim; 
    return POSITIVE(position);                                               	// trebuie rezolvate coliziunile with chaining
}

/*
int hash_alqrainy(int x)                                           // le ia consecutive     ,so not
{
	int position=(x+(prim*3)/7)%prim;
	return POSITIVE(position);
}*/

int main()
{
	NOD *v[m];
	int N,i,a,b,x,k;
	FILE *in,*out;
	in=fopen("hashuri.in","r");
	out=fopen("hashuri.out","w");
	fscanf(in,"%d",&N);
	for(i=0;i<m;i++)
		v[i]=NULL;
	for(i=1;i<=N;i++)
	{
		fscanf(in,"%d %d",&a,&b);
		if(a==1)
		{
			x=hash(b);                       // initializare hash cu NULL
			k=0;
			NOD *p;
			p=v[x];
			while(p!=NULL&&k==0)
			{
				if(p->info==b)
					k=1;
				p=p->next;
			}
			if(k==0)                                  // elementul care trebuie inserat nu se gaseste in hash
			{
				if(v[x]==NULL)                    // daca lista care incepe de la hash[x] e vida
				{
					v[x]=new NOD;
					v[x]->info=b;
					v[x]->next=NULL;
					v[x]->back=NULL;
				}
				else
				{
					p=v[x];
					while(p->next!=NULL)
						p=p->next;
					NOD *r;
					r=new NOD;
					r->info=b;
					r->next=NULL;
					r->back=p;
					p->next=r;
				}
			}
		}
		else
			if(a==2)
			{
				x=hash(b);
				k=0;
				NOD *p,*r;                  // pointerul r este mereu cu un pas in urma lui p
				p=v[x];
				while(p!=NULL&&k==0)
				{
					if(p->info==b)	
						k=1;
					r=p;
					p=p->next;
				}
				if(k==1)                               // elementul care trebuie sters se gaseste in lista v[x]
				{
					if(r==v[x])                   // daca elementul care trebuie sters este primul element din lista v[x]
					{
						NOD *s;s=v[x];
						v[x]=v[x]->next;
						if(v[x]!=NULL)
							v[x]->back=NULL;
						delete s;
					}
					else
					{
						p=r->back;
						p->next=r->next;
						r->next->back=p;
						delete r;
					}
				}
			}
			else
				if(a==3)
				{
					x=hash(b);
					k=0;
					NOD *p;
					p=v[x];
					while(p!=NULL&&k==0)
					{
						if(p->info==b)
							k=1;
						p=p->next;
					}
					fprintf(out,"%d\n",k);
				}
	}
	fclose(in);
	fclose(out);
	return 0;
}