Cod sursa(job #1765110)

Utilizator ReksioCroftOctavian Florin Staicu ReksioCroft Data 26 septembrie 2016 12:33:25
Problema Oite Scor 100
Compilator c Status done
Runda cerculdeinfo-lectia1-hashuri.rabinkarp Marime 1.37 kb
#include <stdio.h>
#define nmax 1024
#define maxcomb 523776 /// ( ( ( 1 + (nmax-1) )* ( nmax - 1 ) ) / 2 )
#define mod 702113
int v[nmax];
int hash[mod];
int val[maxcomb+1];
int next[maxcomb+1];
int frecv[maxcomb+1];
int co, lung;

int caut( int s ){
    int poz = hash[s%mod];
    while( val[poz]!=s && poz!=0 )
        poz = next[poz];
    return poz;
}

void adauga( int s ){
    int poz = caut( s );
    if( poz!=0 )
        frecv[poz]++;
    else{
        val[++lung] = s;
        frecv[lung] = 1;
        next[lung] = hash[ s%mod ];
        hash[s%mod] = lung;
    }

}

void oite( int s ){
    co += frecv[ caut(s) ];
}
int main()
{
    int n, s, i, j;
    FILE *fin, *fout;
    fin = fopen( "oite.in", "r" );
    fscanf( fin, "%d%d", &n, &s );
    for( i=0; i<n; i++ )
        fscanf( fin, "%d", &v[i] );
    fclose( fin );
    for( i=0; i<n; i++ ){       ///inseram elementele in hash ca suma de 2 cate 2 => o(n^4) devine o(n^2)
        for( j=i+1; j<n; j++ ){
            if( s>=v[i]+v[j] )
                oite( s-v[i]-v[j] );    ///daca s - suma ultimelor 2 apare, insemana ca avem 4 oite distincte care au suma s
        }
        for( j=0; j<i; j++ )     ///adaugam suma primelor 2
            adauga( v[i]+v[j] );
    }
    fout = fopen( "oite.out", "w" );
    fprintf( fout, "%d\n", co );
    fclose( fout );

    return 0;
}