Cod sursa(job #1783979)

Utilizator borcanirobertBorcani Robert borcanirobert Data 19 octombrie 2016 17:33:41
Problema Pavare2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.35 kb
#include <fstream>
#include <cstring>
using namespace std;

ifstream fin("pavare2.in");
ofstream fout("pavare2.out");

const int MAX = 105;
const int MAXCIF = 505;
typedef int NrMare[MAXCIF];
int N, A, B;
NrMare K;
NrMare D[MAX][MAX][2];
NrMare s;
int l[2];
char x[MAXCIF];
int ans[MAX];

void Dyn();
void Add( NrMare a, NrMare b );
int Compare( NrMare a, NrMare b ); // < 0 - a < b, 0 - a == b, 1 - a > b
void Copy( NrMare d, NrMare s );
void Minus( NrMare a, NrMare b ); // b < a !!
void Write( NrMare a );
void Cerinta1();
void Cerinta2();
void Sum( int i, int j, bool c );

int main()
{
    fin >> N >> A >> B; fin.get();
    fin.getline(x, MAXCIF);

    int l = strlen(x);
    for ( int i = 1; i <= l; i++ )
        K[i] = x[l - i] - '0';
    K[0] = l;

    Dyn();
    Cerinta1();
    Cerinta2();

    fin.close();
    fout.close();
    return 0;
}

void Dyn()
{
    int i, j, w;
    bool cc, cp;

    D[1][1][0][0] = D[1][1][0][1] = 1;
    D[1][1][1][0] = D[1][1][1][1] = 1;
    l[0] = A, l[1] = B;

    for ( i = 2; i <= N; i++ )
        for ( cc = 0, cp = 1, w = 0; w < 2; cc = !cc, cp = !cp, w++ )
        {
            // j == 1

            memset(s, 0, sizeof(s));
            for ( j = 1; j <= min(l[cp], i - 1); j++ )
                Add(s, D[i - 1][j][cp]);

            Copy(D[i][1][cc], s);

            for ( j = 2; j <= min(l[cc], i); j++ )
                Copy(D[i][j][cc], D[i - 1][j - 1][cc]);
        }
}

void Copy( NrMare d, NrMare s )
{
    for ( int i = 0; i <= s[0]; i++ )
        d[i] = s[i];
}

void Add( NrMare a, NrMare b )
{
    int i, t = 0, cif;

    for ( i = 1; i <= max(a[0], b[0]); i++ )
    {
        cif = ( a[i] + b[i] + t );
        a[i] = cif % 10;
        t = cif / 10;
    }

    a[0] = max( a[0], b[0] );
    while ( t )
        a[++a[0]] = t % 10, t /= 10;
}

int Compare( NrMare a, NrMare b )
{
    if ( a[0] > b[0] ) return 1;
    if ( a[0] < b[0] ) return -1;

    for ( int i = a[0]; i >= 1; i-- )
    {
        if ( a[i] > b[i] ) return 1;
        if ( a[i] < b[i] ) return -1;
    }

    return 0;
}

void Minus( NrMare a, NrMare b )
{
    int i, t = 0, cif;

    for ( i = 1; i <= a[0]; i++ )
    {
        cif = ( a[i] - b[i] ) + t; t = 0;
        while ( cif < 0 )
            t--, cif += 10;

        a[i] = cif;
    }

    while ( a[a[0]] == 0 )
        --a[0];
}

void Write( NrMare a )
{
    int i;

    for ( i = a[0]; i >= 1; i-- )
        fout << a[i];
}

void Cerinta1()
{
    int i;

    memset(s, 0, sizeof(s));
    for ( i = 1; i <= max(A, B); i++ )
    {
        Add(s, D[N][i][0]);
        Add(s, D[N][i][1]);
    }

    Write(s);
    fout << '\n';

    memset(s, 0, sizeof(s));
}

void Cerinta2()
{
    bool uc;
    int nc = 0;
    int i, j;
    int na, nb;

    for ( i = 1; i <= N; i++ )
    {
        na = 1 + ( uc == 0 ? nc : 0 );
        nb = 1 + ( uc == 1 ? nc : 0 );

        Sum(N - i + na, na, 0);
        if ( Compare(s, K) >= 0 )
        {
            ans[i] = 0;
            if ( uc == 0 )
                nc++;
            else
                uc = 0, nc = 1;
        }
        else
        {
            ans[i] = 1;
            if ( uc == 1 )
                nc++;
            else
                uc = 1, nc = 1;

            Minus(K, s);
        }

        fout << ans[i];
    }
}

void Sum( int i, int j, bool c )
{
    int ind;

    memset(s, 0, sizeof(s));

    for ( ind = j; ind <= min(i, l[c]); ind++ )
        Add(s, D[i][ind][c]);
}