Cod sursa(job #526620)

Utilizator AndreyPAndrei Poenaru AndreyP Data 28 ianuarie 2011 21:50:06
Problema Cifre Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <cstdio>
#include <cstdlib>
#define N 11

int a[N][N];
int c,k,ks;

inline void precalc() {
       /* if(c==0) {
        	a[1][0] = 9;
		a[1][1] = 1;
		a[2][0] = 90;
		a[2][1] = 9;

                for(int i=3; i<10; ++i) {
			a[i][0] = a[i-1][0]*9;
			for(int j=1; j<=i; ++j)
				a[i][j] = a[i-1][j]*9 + a[i-1][j-1];
		}

		for(int i=1; i<10; ++i) {
			for(int j=i-1; j>=0; --j)
				a[i][j] += a[i][j+1];
		} 
		return ;
	}   */    

	a[1][0] = 9;
	a[1][1] = 1;

	for(int i=2; i<10; ++i) {
		a[i][0] = a[i-1][0]*9;
		for(int j=1; j<=i; ++j)
			a[i][j] = a[i-1][j]*9 + a[i-1][j-1];
	}

	for(int i=1; i<10; ++i) {
		for(int j=i-1; j>=0; --j)
			a[i][j] += a[i][j+1];
	}
}

inline int rezolva(int nr) {
	k = ks;
	if(nr<0)
		return 0;

	int v[N]={0};
	while(nr!=0) {
		v[++v[0]] = nr%10;
		nr /= 10;
	}

	int ret = 0;

	for(int i=v[0]; i>1; --i) {
		for(int j=0; j<v[i]; ++j) {
			if(j==c && k>0)
				ret += a[i-1][k-1];
			else
				ret += a[i-1][k];
		}
		if(v[i]==c && k>0)
			--k;
	}
        
	if(k==0)
		ret += v[1]+1;
	if(k==1 && c<=v[1])
		++ret;
		
        return ret;
}

inline bool spune(int nr,int k) {
	if(nr==0 && k<2)
		return 1;
	while(nr!=0 && k>0) {
		if(nr%10==0)
			--k;
		nr/=10;
	}

	if(k==0)
		return true;
	return false;
}

int main() {
	freopen("cifre.in","r",stdin);
	freopen("cifre.out","w",stdout);

        /*c = 0;
	precalc();
	for(int i=0; i<10; ++i) {
		ks = i;
		k = ks;
		int cat = 0;
		for(int j=0; j<10000001; ++j) {
			if(spune(j,k))
				++cat;
			if(rezolva(j)!=cat) {
				printf("rezolva(%d) = %d (trebuia -> %d)\n",j,rezolva(j),cat); 
		    		return 0;
			}
		}
		printf("Ok\n");
		return 0;
	}*/      

	int a,b;
	scanf("%d%d%d%d",&a,&b,&c,&k);
	if(c==0 && k<2)
		exit(4);
	ks = k;
	if(k==0) {
		fputs("1.0000\n",stdout);
		return 0;
	}
        precalc();

	int aux = rezolva(b)-rezolva(a-1);

	printf("%.5lf\n",(double)aux/(double)(b-a+1));

	return 0;
}