Cod sursa(job #1996667)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 2 iulie 2017 12:44:48
Problema Submultimi Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <iostream>
#include <fstream>

using namespace std;
ifstream in("submultimi.in");
ofstream out("submultimi.out");
const int NMax = 16 + 5;

int N,nrSol;
int sol[NMax],nrSub[NMax];
// sol - vector unde se genereaza solutiile
// nrSub[i] = numarul de submultimi distincte care se pot forma
//            ce coincid prin primele J elemente,
//            unde J este pozitia pe care s-a pus valoarea i in vectorul sol

void buildSub(int);

int main() {
    in>>N;

    // se construieste nrSub.
    // La dreapta pozitiei unde se pune valoare i
    // se mai pot utiliza elemente doar din multimea {i+1,i+2,...,N}
    // care va avea N-i elemente si deci 2^(N-i) submultimi
    for (int i=1;i <= N;++i) {
        nrSub[i] = 1<<(N-i);
    }

    int lim = 1<<N;
    for (int k=1;k < lim;++k) {
        buildSub(k); // se genereaza a k-a submultime in ordine lexicografica

        // si se afiseaza
        for (int i=1;i <= nrSol;++i) {
            out<<sol[i]<<' ';
        }
        out<<'\n';
    }

    in.close();
    out.close();
    return 0;
}

void buildSub(int k) {
    nrSol = 0;
    int nr = 0; // numarul de ordine al submultimii curente

    for (int i=1;i <= N && nr < k;++i) {
        int low = nr+1,
            high = nr + nrSub[i];
        // low este numarul de ordine al primei multimi care s-ar putea forma
        // daca s-ar pune valoarea i pe urmatoarea pozitie
        // high este numarul de ordine al unei ultime astfel de multimi

        if (k > high) {
            // nu folosim elementul i, deci sarim peste submultimile care s-ar putea genera astfel
            nr = high;
            continue;
        }
        nr = low;
        sol[++nrSol] = i;
    }
}