Cod sursa(job #902799)

Utilizator otto1Palaga Vicentiu-Octavian otto1 Data 1 martie 2013 16:48:17
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <fstream>
#include <cstdio>
#include <cstring>
#define i64 long long

using namespace std;

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

int A, B, C, K;
char num[16];
int numDigits;
int dp[11][11][3];

int memo(int k,int numc,int s) {
    int &ret = dp[k][numc][s];
    if(ret != -1) {
        return ret;
    }
    ret = 0;
    if(numc >= K) {
        if(k < numDigits || s < 2)
            ret++;
    }
    if(k == numDigits) {
        return ret;
    }
    int currDigit = (int)(num[k] - '0');
    if(s == 0) {
        for(int c = (k == 0);c < 10;c++) {
            if(c < currDigit)  {
                ret += memo(k + 1,numc + (C == c),1);
            }
            else
            if(c == currDigit) {
                ret += memo(k + 1,numc + (C == c),0);
            } else {
                ret += memo(k + 1,numc + (C == c),2);
            }
        }
    }
    else {
        for(int c = 0;c < 10;c++) {
            ret += memo(k + 1,numc + (C == c),s);
        }
    }
    return ret;
}


int countNumbers(const int &val) {
    if(val < 0) {
        return 0;
    }
    if(!val) {
        return (K <= 1 && C == 0);
    }
    sprintf(num,"%d",val);
    numDigits = strlen(num);
    memset(dp,-1,sizeof(dp));
    return memo(0,0,0) + (K <= 1 && C == 0);
}

double solve() {
    int ret = countNumbers(B) - countNumbers(A - 1);
    return 1.0*ret/(B - A + 1);
}

int main()
{
    cin>>A>>B>>C>>K;
    cout.precision(4);
    cout<<fixed<<solve();
    return 0;
}