Cod sursa(job #2093809)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 24 decembrie 2017 14:49:38
Problema Cifre Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <fstream>
#include <iomanip>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;

ifstream fin ("cifre.in"); ofstream fout ("cifre.out");

int p9[ 12 ];
int d[ 12 ][ 12 ][ 2 ];

int C (int x, int y) {
    if (x < y) return 0;

    int ans = 1;
    for (int i = x - y + 1; i <= x; ++ i)
        ans *= i;

    for (int i = 1; i <= y; ++ i)
        ans /= i;
    return ans;
}

int solve (int x, int c, int cnt) {
    if (x < 0) return 0;

    vector< int > cif;
    int cpy = x;

    do {
        cif.push_back(cpy % 10);
        cpy /= 10;
    } while (cpy > 0);
    reverse(cif.begin(), cif.end());

    int ans = 0;
    for (int i = 1; i < (int)cif.size(); ++ i) {
        for (int j = cnt; j <= i; ++ j) {
            ans += C(i - (c == 0), j) * p9[i - j];
        }
    }

    // cate au fix cif cifre
    memset(d, 0, sizeof(d));

    for (int i = 1; i <= cif[ 0 ]; ++ i) {
        ++ d[ 1 ][ (i == c) ][ (i == cif[ 0 ]) ];
    }

    for (int i = 2; i <= (int)cif.size(); ++ i) {
        for (int j = 0; j <= i; ++ j) {
            for (int k = 0; k < cif[i - 1]; ++ k) {
                if (j == 0 && k == c) continue;
                d[ i ][ j ][ 0 ] += d[i - 1][j - (k == c)][ 1 ];
            }

            for (int k = 0; k < 10; ++ k) {
                if (j == 0 && k == c) continue;
                d[ i ][ j ][ 0 ] += d[i - 1][j - (k == c)][ 0 ];
            }

            if (j != 0 || cif[i - 1] != c)
                d[ i ][ j ][ 1 ] = d[i - 1][j - (cif[i - 1] == c)][ 1 ];
        }
    }

    for (int i = cnt; i <= (int)cif.size(); ++ i) {
        ans += d[(int)cif.size()][ i ][ 0 ];
        ans += d[(int)cif.size()][ i ][ 1 ];
    }

    if (x < 10 && c == 0)
        return 1;

    return ans;
}

int main () {
    int a, b, c, k;
    fin >> a >> b >> c >> k;

    p9[ 0 ] = 1;
    for (int i = 1; i <= 10; ++ i)
        p9[ i ] = p9[i - 1] * 9;

    fout << setprecision( 7 ) << fixed;

    double p = (double)(solve(b, c, k) - solve(a - 1, c, k)) / (b - a + 1);
    if (k == 0)
        p = 1;
    fout << p << "\n";

    fin.close();
    fout.close();
    return 0;
}