Cod sursa(job #2211087)

Utilizator giotoPopescu Ioan gioto Data 9 iunie 2018 13:01:18
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <bits/stdc++.h>
using namespace std;

int a, b, c, k;
inline int lgput(int x, int p){
    int ans = 1, aux = x;
    for(int i = 0; (1 << i) <= p ; ++i){
        if((1 << i) & p) ans *= aux;
        aux *= aux;
    }
    return ans;
}
inline int comb(int n, int k){
    int ans = 1;
    for(int i = 2; i <= n ; ++i)
        ans *= n;
    for(int i = 2; i <= k ; ++i)
        ans /= i;
    for(int i = 2; i <= n - k ; ++i)
        ans /= i;
    return ans;
}
inline int solve(int x, int c, int k){
    int nrc = 0, aux = x, a[11];
    while(aux > 0) a[++nrc] = aux % 10, aux /= 10;

    if(x == 0 && c == 0 && k == 1) return 1;
    if(k > nrc) return 0;

    int d[15][15];
    memset(d, 0, sizeof(d));
    d[1][0] = 8;
    if(c == 0) ++d[1][0], d[1][1] = 0;
    else d[1][1] = 1;
    for(int i = 2; i < nrc ; ++i){
        d[i][0] = d[i - 1][0] * 9;
        for(int j = 1; j <= i ; ++j)
            d[i][j] = d[i - 1][j] * 9 + d[i - 1][j - 1];
    }
    int ans = 0;
    for(int i = 1; i < nrc ; ++i){
        for(int j = k; j <= i ; ++j)
            ans += d[i][j];
    }
    memset(d, 0, sizeof(d));

    d[1][0] = 9; d[1][1] = 1;
    for(int i = 2; i < nrc ; ++i){
        d[i][0] = d[i - 1][0] * 9;
        for(int j = 1; j <= i ; ++j)
            d[i][j] = d[i - 1][j] * 9 + d[i - 1][j - 1];
    }
    for(int i = 1; i <= nrc / 2 ; ++i)
        swap(a[i], a[nrc - i + 1]);

    for(int i = 1; i <= nrc ; ++i){
        int cr = nrc - i;
        if(k > cr + 1) break ;
        if(k == 0){
            if(i == 1) ans = ans + (a[i] - 1) * lgput(10, cr);
            else ans = ans + a[i] * lgput(10, cr);
            if(cr == 0) ++ans;
            continue ;
        }
        if(cr == 0){
            if(k == 0) ans = ans + a[i];
            else if(k == 1) ans = ans + (c <= a[i]);
            continue ;
        }
        if(i == 1){
            if(c == 0){
                int k2 = k;
                for(int j = k2; j <= cr ; ++j)
                    ans = ans + d[cr][j] * (a[i] - 1);
            }
            else{
                int k2 = k;
                if(c < a[i]){
                    ///il pun pe c
                    --k2;
                    for(int j = k2 + (k2 < 0); j <= cr ; ++j)
                        ans = ans + d[cr][j];
                    ++k2;
                }
                ///nu il pun pe c
                int nr = a[i] - 1 - (c < a[i]);
                if(nr < 0) nr = 1;
                for(int j = k2; j <= cr ; ++j)
                    ans = ans + d[cr][j] * nr;
            }
        }
        else{
            int k2 = k;
            if(c < a[i]){
                ///il pun pe c
                --k2;
                for(int j = k2 + (k2 < 0); j <= cr ; ++j)
                    ans = ans + d[cr][j];
                ++k2;
            }
            ///nu il pun pe c
            int nr = a[i] - (c < a[i]);
            if(nr < 0) nr = 0;
            for(int j = k2; j <= cr ; ++j)
                ans = ans + d[cr][j] * nr;
        }

        if(a[i] == c && k > 0) --k;
    }
    return ans;
}
int main()
{
    freopen("cifre.in", "r", stdin);
    freopen("cifre.out", "w", stdout);
    scanf("%d%d%d%d", &a, &b, &c, &k);
    int nr = solve(b, c, k) - solve(a - 1, c, k);
    double sol = (double)nr / (double)(b - a + 1);
    printf("%f", sol);
    return 0;
}