Cod sursa(job #1773856)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 8 octombrie 2016 12:14:03
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cstring>

using namespace std;

int dp[20][20][2]; //dp[where][K][<]

int nr[20];
int n;

int cnt(int len, int C, int K) {
    for (int where = 0; where < len; ++ where)
        for (int k = 0; k <= K; ++ k)
            if (dp[where][k][0] || dp[where][k][1]) {
                for (int digit = (where == 0); digit < 10; ++ digit) {
                    if (digit < nr[where + 1]) {
                        dp[where + 1][k + (digit == C)][1] += dp[where][k][0];
                        dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
                    }
                    else if (digit == nr[where + 1]) {
                        dp[where + 1][k + (digit == C)][0] += dp[where][k][0];
                        dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
                    }
                    else
                        dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
                }
            }

    int ans = 0;
    for (int k = 0; k <= K; ++ k)
        ans += dp[len][k][0] + dp[len][k][1];
    return ans;
}

int solve(int NR, int C, int K) {
    if (NR == -1)
        return 0;
    if (NR == 0)
        return ((C == 0 && K > 0) || C > 0);

    n = 0;

    while (NR) {
        nr[++ n] = NR % 10;
        NR /= 10;
    }

    reverse(nr + 1, nr + n + 1);

    int ans = 0;

    //Length smaller than n
    for (int i = 1; i < n; ++ i) {
        memset(dp, 0, sizeof dp);
        dp[0][0][1] = 1;
        int aux = cnt(i, C, K);
        ans += aux;
    }

    //Length exactly n
    memset(dp, 0, sizeof dp);
    dp[0][0][0] = 1;
    int aux = cnt(n, C, K);
    ans += aux;

    //0 itself
    if ((C == 0 && K > 0) || C > 0)
        ++ ans;

    return ans;
}

int getAns(int A, int B, int C, int K) {
    return B - A + 1 - solve(B, C, K - 1) + solve(A - 1, C, K - 1);
}

int main()
{
    ifstream cin("cifre.in");
    ofstream cout("cifre.out");

    int A, B, C, K;
    cin >> A >> B >> C >> K;

    cout << fixed << setprecision(4) << getAns(A, B, C, K) / (B - A + 1.0) << '\n';

    cin.close();
    cout.close();
    return 0;
}