Cod sursa(job #865531)

Utilizator ELHoriaHoria Cretescu ELHoria Data 26 ianuarie 2013 16:56:46
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.41 kb
#include <fstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#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 val) {
    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,val*10 + c);
			}
			else
			if(c == currDigit) {
				ret += memo(k + 1,numc + (C == c),0,val*10 + c);
			} else {
				ret += memo(k + 1,numc + (C == c),2,val*10 + c);
			}
		}
	}
	else {
		for(int c = 0;c < 10;c++) {
			ret += memo(k + 1,numc + (C == c),s,val*10 + c);
		}
    }
    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,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;
}