Cod sursa(job #818715)

Utilizator visanrVisan Radu visanr Data 17 noiembrie 2012 20:59:15
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

//dp[i][j][k][l] - nr de numere de i cifre care contin j cifre C, k = 0/1 daca pot pune orice / nu, l = 0 / 1 daca am pus cifra nenula / nu
#define pb push_back

int dp[15][15][2][2];
int A, B, C, K, N;
vector<int> V;

int Digits(int val)
{
    V.clear();
    int ans = 0;
    while(val)
    {
        V.pb(val % 10);
        ans ++;
        val /= 10;
    }
    reverse(V.begin(), V.end());
    return ans;
}

int Dp(int val)
{
    memset(dp, 0, sizeof(dp));
    N = Digits(val);
    dp[0][0][1][0] = 1;
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
            for(int k = 0; k < 2; k++)
                for(int l = 0; l < 2; l++)
                    for(int digit = 0; digit < 10; digit ++)
                    {
                        int ii, jj, kk, ll;
                        if(k == 1 && digit > V[i]) continue;
                        ii = i + 1;
                        if(digit == C && (C != 0 || l == 1)) jj = j + 1;
                        else jj = j;
                        if(k == 1 && digit == V[i]) kk = 1;
                        else kk = 0;
                        if(l == 0 && digit == 0) ll = 0;
                        else ll = 1;
                        dp[ii][jj][kk][ll] += dp[i][j][k][l];
                    }
    int ans = 0;
    for(int i = K; i <= N; i++) ans += dp[N][i][0][1] + dp[N][i][1][1];
    if(C == 0) return ans + 1;
    else return ans;
}

int main()
{
    freopen("cifre.in", "r", stdin);
    freopen("cifre.out", "w", stdout);
    scanf("%i %i %i %i", &A, &B, &C, &K);
    printf("%lf\n", 1.0 * (Dp(B) - Dp(A - 1)) / (B - A + 1));
    return 0;
}