Cod sursa(job #2294886)

Utilizator gigelmargelgigel margel gigelmargel Data 2 decembrie 2018 22:02:27
Problema Abc2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>

using namespace std;

const unsigned int p = 1000000009;

unsigned int hashString(char *s)
{
    unsigned long long hs = 0, p3 = 1;
    int i ;
    for ( i = strlen(s)-1 ; i >= 0; i--)
    {
        hs = hs + p3 * (s[i]-'a' + 1);
        p3 = 3 * p3;
    }
    return (unsigned int)(hs % p);
}

int cautareBinara(unsigned int *dictionar, unsigned int nrcuv, unsigned int x)
{
    unsigned int mij, st = 0, dr = nrcuv - 1;

    if(x < dictionar[st] || x > dictionar[dr])
        return 0;

    while(st <= dr)
    {
        mij = st + (dr - st)/2;
        if(dictionar[mij] == x)
            return 1;
        if(x < dictionar[mij])
            dr = mij - 1;
        else
            st = mij + 1;
    }

    return 0;
}

int cmpHash(const void *a, const void *b)
{
    unsigned int va = *(unsigned int *)a;
    unsigned int vb = *(unsigned int *)b;

    if(va < vb) return -1;
    if(va > vb) return +1;
    return 0;
}

int main()
{
    unsigned int *dictionar;

    char cuv[23], *text;

    double t = clock();

    FILE *f = fopen("abc2_max.in", "r");

    text = (char *)malloc(10000001);

    fgets(text, 10000001, f);
    fgetc(f);

    int ltext = strlen(text);

    if(text[strlen(text) - 1] == '\n')
    {
        text[strlen(text) - 1] = '\0';
        ltext--;
    }

    unsigned int lcuv = 0;
    unsigned int nrcuv = 0;

    dictionar = (unsigned int *)malloc(50000 * sizeof(unsigned int));

    while (fgets(cuv, 23, f) != NULL)
    {
        if(cuv[strlen(cuv) - 1] == '\n')
            cuv[strlen(cuv) - 1] = '\0';

        if(lcuv == 0)
            lcuv = strlen(cuv);

        dictionar[nrcuv++] = hashString(cuv);
    }

    qsort(dictionar, nrcuv, sizeof(unsigned int), cmpHash);

    fclose(f);

    int nr = 0;

    strncpy(cuv, text, lcuv);
    cuv[lcuv] = '\0';

    unsigned long long int p3 = 1;
    for(unsigned int i = 0; i < lcuv - 1; i++)
        p3 = 3 * p3;

    unsigned long long int crt_hash = hashString(cuv);
    if(cautareBinara(dictionar, nrcuv, (unsigned int)crt_hash) == 1)
        nr++;

    for(unsigned int i = 1; i <= ltext - lcuv; i++)
    {
        crt_hash = crt_hash - (text[i-1] - 'a' + 1) * p3;
        crt_hash = 3 * crt_hash;
        crt_hash = (crt_hash + text[i + lcuv-1] - 'a' + 1) % p;

        if(cautareBinara(dictionar, nrcuv, (unsigned int)crt_hash) == 1)
            nr++;
    }

    free(text);

    free(dictionar);

    f = fopen("abc2.out", "w");

    fprintf(f, "%d", nr);

    fclose(f);

    t = clock() - t;
    printf("\nTimp de executare = %.6f\n", t/CLOCKS_PER_SEC);

    return 0;
}