Cod sursa(job #5539)

Utilizator astronomyAirinei Adrian astronomy Data 12 ianuarie 2007 23:08:11
Problema Cifre Scor 80
Compilator c Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <stdio.h>

#define max(a,b) ((a) > (b) ? (a) : (b))

int A, B, C, K, comb[16][16], p9[16];
int V[16];

int get(int n, int k)
{
    return comb[n][k]*p9[n-k];
}

int F(int n, int k)
{
    int i, j, c = V[n], res = 0;

    k = max(k, 0);

    if(n == 1)
    {
        if(k == 0) return c+1;
        if(k == 1) return C <= c ? 1 : 0;
        return 0;
    }
    
    for(i = 0; i < c; i++)
    {
        if(C == i)
        {
            for(j = k-1; j < n; j++)
                res += get(n-1, j);
            continue ;
        }
        for(j = k; j < n; j++)
            res += get(n-1, j);
    }

    if(C == c)
        res += F(n-1, k-1);
    else
        res += F(n-1, k);

    return res;
}

int solve(int A)
{
    int i, nr = 0, j, t[16], cnt, c, n = 0, res = 0;

    if(A < 0)
        return 0;
        
    if(A <= 100)
    {
        for(i = 0; i <= A; i++)
        {
            nr = 0, c = i;
            t[++nr] = c % 10, c /= 10;
            while(c)
                t[++nr] = c % 10, c /= 10;
            for(cnt = 0, j = 1; j <= nr; j++)
             if(t[j] == C)
                cnt++;
            if(cnt >= K)
                res++;
        }
        return res;
    }

    while(A)
        V[++n] = A % 10, A /= 10;

    c = V[n];
    
    if(C == 0)
    {
        for(i = 1; i < c; i++)
         for(j = K; j < n; j++)
            res += get(n-1, j);
        for(i = n-1; i >= 2; i--)
         for(j = K; j <= i; j++)
            res += 9*get(i-1, j);
        res += F(n-1, K);
    }
    else
    {
        for(i = 1; i < c; i++)
         if(C == i)
         {
            for(j = K-1; j < n; j++)
                res += get(n-1, j);
         }
         else
            for(j = K; j < n; j++)
                res += get(n-1, j);
        for(i = n-1; i >= 1; i--)
         for(j = K; j <= i; j++)
            res += get(i, j);
        if(c == C)
            res += F(n-1, K-1);
        else
            res += F(n-1, K);
    }

    return res;
}

int main(void)
{
    freopen("cifre.in", "rt", stdin);
    freopen("cifre.out", "wt", stdout);

    int i, n, k;
    double res;

    for(n = 1; n <= 10; n++)
     for(comb[n][1] = n, k = 2; k <= n; k++)
        comb[n][k] = comb[n-1][k-1]+comb[n-1][k];

    for(p9[0] = 1, n = 1; n <= 9; n++)
        p9[n] = 9*p9[n-1];
        
    scanf("%d %d %d %d\n", &A, &B, &C, &K);

    res = (double)( solve(B)-solve(A-1) ) / (B-A+1);

    printf("%.4lf\n", res);

    return 0;
}