Cod sursa(job #1730724)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 17 iulie 2016 15:27:52
Problema Pavare2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 110
#define MAXDIGITS 40
using namespace std;
int dp[MAXN][2][MAXN][MAXDIGITS],limit[2],k[MAXDIGITS],temp[MAXDIGITS];
char s[MAXDIGITS];
void Add(int a[],int b[]){
    int i,c=0,n;
    if(a[0]<b[0])
        n=b[0];
    else
        n=a[0];
    for(i=1;i<=n;i++){
        if(i>a[0])
            a[i]=0;
        if(i>b[0])
            b[i]=0;
        a[i]=a[i]+b[i]+c;
        c=a[i]/10;
        a[i]%=10;
    }
    a[0]=n;
    while(c>0){
        a[0]++;
        a[a[0]]=c%10;
        c/=10;
    }
}
void Subtract(int a[],int b[]){
    int i,c=0;
    for(i=1;i<=a[0];i++){
        if(i>b[0])
            b[i]=0;
        a[i]=a[i]-b[i]-c;
        if(a[i]<0){
            a[i]+=10;
            c=1;
        }
        else
            c=0;
    }
    while(a[0]>0&&a[a[0]]==0)
        a[0]--;
}
int Compare(int a[],int b[]){
    int i;
    if(a[0]>b[0])
        return 1;
    if(a[0]<b[0])
        return -1;
    for(i=a[0];i>=1;i--){
        if(a[i]>b[i])
            return 1;
        if(a[i]<b[i])
            return -1;
    }
    return 0;
}
int main(){
    freopen("pavare2.in","r",stdin);
    freopen("pavare2.out","w",stdout);
    int n,i,j,color,current=-1,previous=0,start,ok,l;
    scanf("%d%d%d\n",&n,&limit[0],&limit[1]);
    scanf("%s",s+1);
    k[0]=strlen(s+1);
    for(i=k[0];i>=1;i--)
        k[i]=s[k[0]-i+1]-'0';
    dp[1][0][1][0]=dp[1][0][1][1]=dp[1][1][1][0]=dp[1][1][1][1]=1;
    for(i=2;i<=n;i++)
        for(color=0;color<=1;color++){
            temp[0]=0;
            for(j=1;j<=limit[color^1];j++)
                Add(temp,dp[i-1][color^1][j]);
            Add(dp[i][color][1],temp);
            for(j=2;j<=limit[color];j++)
                Add(dp[i][color][j],dp[i-1][color][j-1]);
        }
    temp[0]=0;
    for(color=0;color<=1;color++)
        for(i=1;i<=limit[color];i++)
            Add(temp,dp[n][color][i]);
    for(i=temp[0];i>=1;i--)
        printf("%d",temp[i]);
    printf("\n");
    i=n;
    while(i>0){
        start=limit[0];
        if(current==0)
            start-=previous;
        start=min(start,i);
        ok=0;
        if(current!=0)
            for(j=start;j>0;j--){
                if(Compare(k,dp[i][0][j])==1){
                    Subtract(k,dp[i][0][j]);
                    continue;
                }
                i-=j;
                for(l=1;l<=j;l++)
                    printf("0");
                if(current==0)
                    previous+=j;
                else
                    previous=j;
                current=0;
                ok=1;
                break;
            }
        if(ok==1)
            continue;
        start=limit[1];
        if(current==1)
            start-=previous;
        start=min(start,i);
        ok=0;
        if(current!=1)
            for(j=1;j<=start;j++){
                if(Compare(k,dp[i][1][j])==1){
                    Subtract(k,dp[i][1][j]);
                    continue;
                }
                i-=j;
                for(l=1;l<=j;l++)
                    printf("1");
                if(current==1)
                    previous+=j;
                else
                    previous=j;
                current=1;
                ok=1;
                break;
            }
    }
    return 0;
}