Cod sursa(job #112229)

Utilizator stef2nStefan Istrate stef2n Data 3 decembrie 2007 21:40:26
Problema Cifre Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <cstdio>
#include <utility>
#include <algorithm>
using namespace std;

int A, B, C, K;

pair <int, int> first(int A)
{
    int p10=1;
    while(A>9)
    {
        A/=10;
        p10*=10;
    }
    return make_pair(A,p10);
}

int lung(int A)
{
    int z=0;
    while(A>9)
    {
        z++;
        A/=10;
    }
    return z;
}

int Comb(int n, int k)
{
    if(k==0 || k==n)
        return 1;
    return Comb(n-1,k)+Comb(n-1,k-1);
}

int power(int a, int n)
{
    if(!n)
        return 1;
    int tmp=power(a,n/2);
    if(n&1)
        return tmp*tmp*a;
    else
        return tmp*tmp;
}

int solve(int A, int C, int K)
{
    if(!K)
        return A+1;
    if(A<10)
        return K==1 && A>=C;
    pair <int, int> p = first(A);
    if(!C)
    {
        int sum=0, l=lung(p.second);
        for(int tmp=K; tmp<=l; ++tmp)
            sum+=Comb(l,tmp)*power(9,l-tmp);
        return (p.first-1)*sum+solve(p.second-1,C,K)+
            solve(A%p.second,C,max(K-(l-lung(A%p.second)-1),0));
    }
    else
    {
        int sol=0;
        int tmp=solve(p.second-1,C,K);
        for(int i=0; i<p.first; ++i)
            if(i!=C)
                sol+=tmp;
            else
                sol+=solve(p.second-1,C,K-1);
        if(p.first==C)
            sol+=solve(A%p.second,C,K-1);
        else
            sol+=solve(A%p.second,C,K);
        return sol;
    }
}


int main()
{
    freopen("cifre.in","r",stdin);
    freopen("cifre.out","w",stdout);
    scanf("%d %d %d %d", &A, &B, &C, &K);
    int cntB = solve(B,C,K);
    int cntA = (A==0) ? 0 : solve(A-1,C,K);
    printf("%.4lf\n",(double)(cntB-cntA)/(double)(B-A+1));
    return 0;
}