Cod sursa(job #886667)

Utilizator alexandru_lucianAlexandru Florin Lucian alexandru_lucian Data 23 februarie 2013 09:39:10
Problema Subsir crescator maximal Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 1.92 kb
#include <stdio.h>
#define Lgmax 150000

FILE *fin, *fout;

int Best[Lgmax], Poz[Lgmax], Vector[Lgmax], Vectorfinal[Lgmax];

int binar (int panala, int val);

int main()
{
    fin =fopen ("subsir.in", "r");
    fout =fopen ("subsir.out", "w");
    int i, n, poz, lung, caut;
    fscanf (fin, "%d", &n);
    for (i=0; i<n; i++)
        fscanf (fin, "%d", &Vector[i]);
    lung=0;
    for (i=0; i<n; i++)
    {
        poz=binar(lung, Vector[i]);
        if (poz==-1)
        {
            lung++;
            Best[lung]=Vector[i];
            Poz[i]=lung;
        }
        else
        {
            Best[poz]=Vector[i];
            Poz[i]=poz;
        }
    }
    fprintf (fout, "%d\n", lung);
    caut=lung;
    for (i=n-1; i>=0; i++)
        if (Poz[i]==caut)
        {
            Vectorfinal[lung-caut]=Vector[i];
            caut--;
        }
    for (i=0; i<lung; i++)
        fprintf (fout, "%d ", Vectorfinal[i]);
    fprintf (fout, "\n");
    fclose (fout);
    return 0;
}

int binar (int panala, int val)
{
    int dela=1, bueno=-1;
    while (dela<=panala)
    {
        if (val<Best[(dela+panala)/2])
        {
            bueno=(dela+panala)/2;
            dela=(dela+panala)/2+1;
        }
        else
            panala=(dela+panala)/2-1;
    }
    return bueno;
}

/*
Best[i] cel mai mic element cu care se poate termina un subsir de lungime i
Poz[i] locul in subsir a elementului i din vector
la pasul i caut (binar) cel mai mic element din Best mai mare decat Vector[i]
daca l-am gasit, inlocuiesc Best[pozitie_gasita] cu Vector[i]
daca nu l-am gasit, il adaugam la sfarsitul lui Best
actualizez Poz[i]
la final, lungimea vectorului Best este lungimea celui mai mic sir crescator
pentru reconstituire, pornim de la sfarsitul lui Vector si-l cautam pe k(=lg(Best))
dupa ce l-am gasit, cautam in continuare spre stanga si-l cautam pe k-1 (se repeta pasul initial)
*/