Cod sursa(job #1740619)

Utilizator sulzandreiandrei sulzandrei Data 11 august 2016 21:22:45
Problema Combinari Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.27 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("combinari.in");
ofstream out("combinari.out");
bool as,ev;
int n,p;
struct Combinare
{
    int n,p;
    bool as,ev;
    Combinare(int a, int b):n(a),p(b){};
    void valid(int k, int *v, bool &ev)//aici vedem daca solutia ce contine primele k elemente in vectoru v este corect
    {
        int i;
        ev = true;
        if( k > 0 && v[k]<=v[k-1])// daca avem cel putin 2 elemente si elementul de pe pozitia k > ala de pe k-1 automat va fi mai mare ca toate altfel nui bine
            ev = false;
    }
    void init( int k, int  *v)//aici initalizam elementul de pe pozitia k cu valoarea precedenta valori minime a unui element din solutie adik 1-1=0
    {
        v[k] = 0;
    }
    void suc(int k, int v[], bool &as)//aici vedem daca pe pozitia k mai exista un succesor(o valoare posibila) pentru in vectorul v si daca da o luam
    {
        if( v[k]< n-p+k+1)//putem avea pe pozitia k o valoare cel mult egala cu n-p+nrpozitiei adica n-p+k+1
        {
            v[k]++;
            as = true;
        }
        else
            as = false;

    }
    int* vectorSolutie(int k, int v[])//aici returnam vectorul ce contine solutia
    {
        int * comb = new int[k+1];
        for(int i = 0 ; i < p; i ++)
            comb[i] = v[i] ;
        return comb;
    }
    bool solutie(int k)//functia solutie ne spune daca lungimea vectorului solutiei este corecta
    {
        if(k == p-1)
            return true;
        return false;
    }
    int ** Cnp(int & nrofCnp)
    {
        nrofCnp = 0;
        int ** combinari = new int*[(1<< n)+4];

        int v[n];
        int k = 0;
        init(k,v);
        while( k>-1 )//cat timp avem elemente pe care le putem verifica in vectoru v
        {
            do//aici cat timp avem solutie pe pozitia k din vector si inca nu e valida
            {
                suc(k,v,as);// in cazul in care pe pozitia k urmatoarea valoarea e corecta atunci o acceptam si facem as = true
                //altfel nu e posibila o noua val si facem as = false
                if(as)//daca a fost acceptata o noua valoarea pe pozitia k vedem daka e valida pentru solutie
                    valid(k,v,ev);
            }
            while( as  && !(as && ev));//deci ne oprim cand ori nu am gasit o valoarea posibila pe positia k ori am gasit si respecta conditiile
            if (as)//daca am gasit valoarea posibila pe pozitia k inseamna ca trebuie sa testam daca pozitia k este si finala
                if(solutie(k))//daca k e finala atunci doar afisam solutia
                    combinari[++nrofCnp] = vectorSolutie(k,v);
                else//altfel vedem solutia posibila pe urmatoarea valoare din vector
                {
                    k++;
                    init(k,v);
                }
            else//altfel ne intoarcem cu un pas inapoi pentru a marii valoare posibila pe acea pozitie
                k--;
        }
        return combinari;
    }
};
int main()
{
    int n,p,nr;
    in >> n >> p;
    Combinare c(n,p);
    int ** sol = c.Cnp(nr);
    for(int i = 1 ; i <= nr ; i ++)
    {
        for(int j = 0  ; j < p ; j ++)
            out << sol[i][j] << " ";
        out <<'\n';
    }
    return 0;
}