Cod sursa(job #1014551)

Utilizator poptibiPop Tiberiu poptibi Data 22 octombrie 2013 21:13:45
Problema Pavare2 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.47 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int NMAX = 110, DigitMax = 100;

int N, A, B;

class Huge
{
    public: int V[DigitMax];
    Huge ()
    {
        memset(V, 0, sizeof(V));
    }
    Huge (int X)
    {
        *this = X;
    }

    Huge operator= (int X)
    {
        memset(V, 0, sizeof(V));
        for(; X; X /= 10)
            V[++V[0]] = X % 10;
        return *this;
    }
    
    Huge operator= (Huge X)
    {
        memcpy(V, X.V, sizeof(X.V));
        return *this;
    } 
    
    Huge operator+ (Huge X) const
    {
        int i, T = 0;
        Huge Now;
        for(i = 1; i <= V[0] || i <= X.V[0] || T; i++, T /= 10)
            Now.V[i] = (T += V[i] + X.V[i]) % 10;
        Now.V[0] = i - 1;
        return Now;
    }

    Huge operator- (Huge X) const 
    {
        int i, T = 0;
        Huge Now;
        Now.V[0] = V[0];
        for(i = 1; i <= V[0]; ++ i)
        {
            Now.V[i] = V[i];
            Now.V[i] -= ((i <= X.V[0]) ? X.V[i] : 0) + T;
            Now.V[i] += (T = Now.V[i] < 0) * 10;
        }
        for(; Now.V[0] > 1 && !Now.V[Now.V[0]]; Now.V[0] --);
        return Now;
    }
    
    void Print() const
    {
        for(int i = V[0]; i; i--) printf("%d", V[i]);
        printf("\n");
    }
};

int Comp(Huge A, Huge B)
{
    if(A.V[0] != B.V[0])
    {
        if(A.V[0] < B.V[0]) return -1;
        return 1;
    }
    
    for(int i = A.V[0]; i; -- i)
        if(A.V[i] != B.V[i])
        {
            if(A.V[i] < B.V[i]) return -1;
            return 1;
        }
    return 0;
}

Huge K, Dp[NMAX][NMAX][2], Ways;
char S[NMAX], Posib[NMAX];

int main()
{
    freopen("pavare2.in", "r", stdin);
    freopen("pavare2.out", "w", stdout);
    
    scanf("%i %i %i\n", &N, &A, &B);
    gets(S + 1);
    
    int M = strlen(S + 1);
    
    for(int i = 1; i <= M; ++ i)
        K.V[++K.V[0]] = S[i] - '0';
    
    Dp[1][1][0] = Dp[1][1][1] = 1;
    for(int i = 1; i < N; ++ i)
        for(int k = 0; k < 2; ++ k)
        {
            if(k == 0)
            {
                for(int j = 0; j <= A; ++ j)
                {
                    if(j != A) Dp[i + 1][j + 1][k] = Dp[i + 1][j + 1][k] + Dp[i][j][k];
                    Dp[i + 1][1][1 - k] = Dp[i + 1][1][1 - k] + Dp[i][j][k];
                }
            }else 
            {
                for(int j = 0; j <= B; ++ j)
                {
                    if(j != B) Dp[i + 1][j + 1][k] = Dp[i + 1][j + 1][k] + Dp[i][j][k];
                    Dp[i + 1][1][1 - k] = Dp[i + 1][1][1 - k] + Dp[i][j][k];
                }
            }
        }
    
    Ways = 0;
    for(int i = 0; i <= A; ++ i)
        Ways = Ways + Dp[N][i][0];
    for(int i = 0; i <= B; ++ i)
        Ways = Ways + Dp[N][i][1];
    Ways.Print();
    
    int Last = -1, Nr_Filled = 0;
    for(int i = A; i; -- i)
        if(Comp(Dp[N][i][0], K) < 0)
            K = K - Dp[N][i][0];
        else 
        {
            Nr_Filled = i;
            Last = 0;
            break;
        }
    
    if(Last == -1)
    {
        for(int i = 1; i <= B; ++ i)
            if(Comp(Dp[N][i][1], K) < 0)
                K = K - Dp[N][i][1];
            else 
            {
                Nr_Filled = i;
                Last = 1;
                break;
            }
    }
    
    for(int i = 1; i <= Nr_Filled; ++ i) Posib[i] = Last + '0';
    
    while(Nr_Filled < N)
    {
        if(Last == 0)
        {
            for(int i = 1; i <= B; ++ i)
                if(Comp(Dp[N - Nr_Filled][i][1], K) < 0)
                    K = K - Dp[N - Nr_Filled][i][1];
                else 
                {
                    for(int j = 1; j <= i; ++ j)
                        Posib[Nr_Filled + j] = '1';
                    Nr_Filled += i;
                    Last = 1;
                    break;
                }
        }else 
        {
            for(int i = A; i > 0; -- i)
                if(Comp(Dp[N - Nr_Filled][i][0], K) < 0)
                    K = K - Dp[N - Nr_Filled][i][0];
                else 
                {
                    for(int j = 1; j <= i; ++ j)
                        Posib[Nr_Filled + j] = '0';
                    Nr_Filled += i;
                    Last = 0;
                    break;
                }
        }
    }
    
    for(int i = 1; i <= N; ++ i)
        printf("%c", Posib[i]);
    
    return 0;
}