Cod sursa(job #51004)

Utilizator varuvasiTofan Vasile varuvasi Data 9 aprilie 2007 17:43:09
Problema Oite Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <stdio.h>
#define FOR(i, a, b) for (i = (a); i <= (b); i++)
#define MaxN 1025

int N, S;
int val[MaxN], sums[515*1025], ind[515*1025], ksum;
int nr[MaxN];
int cnt;

void qsort(int lf, int rt)
{
    int i = lf - 1, j = rt + 1;
    if (lf >= rt) return;
    do
    {
        do { i++; } while (val[lf] > val[i]);
        do { j--; } while (val[lf] < val[j]);
        if (i < j)
        {
            int aux = val[i]; val[i] = val[j]; val[j] = aux;
        }
    } while (i < j);
    qsort(lf, j);
    qsort(j + 1, rt);
}

void qsort2(int lf, int rt)
{
    int i = lf - 1, j = rt + 1;
    if (lf >= rt) return;
    do
    {
        do { i++; } while (sums[lf] > sums[i]);
        do { j--; } while (sums[lf] < sums[j]);
        if (i < j)
        {
            int aux = sums[i]; sums[i] = sums[j]; sums[j] = aux;
            aux = ind[i]; ind[i] = ind[j]; ind[j] = aux;
        }
    } while (i < j);
    qsort2(lf, j);
    qsort2(j + 1, rt);
}

int cbin(int sum)
{
    int st = 1, dr = ksum, ans = 0;
    while (st <= dr)
    {
        int mij = (st + dr) / 2;
        if (sum == sums[mij])
        {
            ans = mij;
            dr = mij - 1;
        }
        else
           if (sum > sums[mij])
                st = mij + 1;
           else dr = mij - 1;
    }        
    return ans;
}

int main()
{
    int i, j;
    FILE *fin = fopen("oite.in", "rt");
    fscanf(fin, "%d %d", &N, &S);
    FOR(i, 1, N)
        fscanf(fin, "%d", &val[i]);
    fclose(fin);
    
    qsort(1, N);
    
    FOR(i, 1, N)
    {
        nr[i] = ksum+1;
        FOR(j, i + 1, N)
        {
            sums[++ksum] = val[i] + val[j];
            ind[ksum] = ksum;
        }    
    }
    nr[N+1] = ksum+1;
    
    qsort2(1, ksum);
    
    int sum, pos;
    
    FOR(i, 1, N)
        FOR(j, i + 1, N)
        {
            sum = S - val[i] - val[j];
			pos = cbin(sum);
			if (pos == 0) continue;

            while (sums[pos] == sum)
            {
                if (ind[pos] >= nr[j+1]) cnt++;
                pos++;
            }
        }
            
    FILE *fout = fopen("oite.out", "wt");
    
    fprintf(fout, "%d\n", cnt);
    
    //DEBUG
    /*FOR(i, 1, N) 
        fprintf(fout, "%d ", val[i]);
    fprintf(fout, "\n");
    FOR(i, 1, ksum)
        fprintf(fout, "%d ", sums[i]);
    fprintf(fout, "\n");
    FOR(i, 1, ksum)
        fprintf(fout, "%d ", ind[i]);
    fprintf(fout, "\n");
    FOR(i, 1, N)
        fprintf(fout, "%d ", nr[i]);*/
    //DEBUG
        
    fclose(fout);
    
    return 0;
}