Cod sursa(job #1774472)

Utilizator silkMarin Dragos silk Data 8 octombrie 2016 23:46:44
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <cstdio>
#define NMax 10

int T[NMax+1][NMax+1];
int X[NMax+1][NMax+1];
int a[NMax+1];
int b[NMax+1];
int pwr[NMax+1];
int A,B,C,K;

void Precalc()
{
    int i,j;

    T[0][0] = 1;
    for(i = 1; i <= NMax; ++i) T[i][0] = 1;
    for(i = 1; i <= NMax; ++i)
        for(j = 1; j <= i; ++j) T[i][j] = T[i-1][j-1] + T[i-1][j];

    pwr[0] = 1;
    for(i = 1; i <= NMax; ++i) pwr[i] = pwr[i-1] * 9;

    for(i = K; i <= NMax; ++i)
    {
        for(j = 1; j < i; ++j )
        {
            X[i][j] = T[i-1][j] * pwr[i-j-1] * ( 9 - ( C>0 ) );
            if( C ) X[i][j] = X[i][j] + T[i-1][j-1] * pwr[i-j];
        }
        X[i][i] = 1;
    }
}

int main(){
    freopen("cifre.in","r",stdin);
    freopen("cifre.out","w",stdout);

    int i,j,lgA,lgB,x,low,noA,noB,nrA,nrB,temp,ans=0;

    scanf("%d %d %d %d",&A, &B, &C, &K);
    Precalc();

    if(!K) { printf("%.4f",1.0); return 0; }

    x = A/10;
    lgA = 1;
    while(x) { ++lgA; x/=10; }

    x = B/10;
    lgB = 1;
    while(x) { ++lgB; x/=10; }

    for(i = lgA+1; i < lgB; ++i)
        for(j = K; j <= i; ++j)
        ans = ans + X[i][j];

    x = A;
    for(i = lgA; i >= 1; --i, x/=10) a[i] = x%10;
    x = B;
    for(i = lgB; i >= 1; --i, x/=10) b[i] = x%10;

    noA = noB = nrA = nrB = 0;

    low = K;
    for(i = 1; i <= lgA; ++i)
    {
        if( a[i] )
        {
            for(j = low; j <= lgA-i; ++j)
            noA = noA + ( a[i] - (i==1) - (a[i]>C) + (i==1 && !C) ) * T[lgA-i][j] * pwr[lgA-i-j];

            if( a[i] > C && ( C || i > 1 ) )
            {
                for(j = low-1; j <= lgA-i; ++j)
                noA = noA + T[lgA-i][j] * pwr[lgA-i-j];
            }
        }
        if( a[i]==C ) --low;
    }

    low = K;
    for(i = 1; i <= lgB; ++i)
    {
        if( b[i] )
        {
            for(j = low; j <= lgB-i; ++j)
            nrB = nrB + ( b[i] - (i==1) - (b[i]>C) + (i==1 && !C) ) * T[lgB-i][j] * pwr[lgB-i-j];

            if( b[i] > C && ( C || i > 1 ) )
            {
                for(j = low-1; j <= lgB-i; ++j)
                nrB = nrB + T[lgB-i][j] * pwr[lgB-i-j];
            }
        }
        if( b[i]==C ) --low;
    }

    temp = 0; x = B;
    while(x) { if(x%10==C) ++temp; x/=10; }
    if( temp >= K ) ++nrB;

    for(i = K; i <= lgA; ++i) nrA = nrA + X[lgA][i];
    nrA = nrA - noA;

    for(i = K; i <= lgB; ++i) noB = noB + X[lgB][i];
    noB = noB - nrB;

    if(lgA==lgB) ans = ans + nrB - noA;
    else ans = ans + nrA + nrB;

    printf("%.4f\n", (double)ans/(B-A+1) );




return 0;
}