Cod sursa(job #3245395)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 28 septembrie 2024 19:48:52
Problema Cifre Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.13 kb
// Ilie "The-Winner" Dumitru
#include<cstdio>
const int NMAX=15;

long long fact[NMAX];
long long p9[NMAX], p10[NMAX];

void precalc()
{
	int i;

	p10[0]=p9[0]=fact[0]=1;
	for(i=1;i<NMAX;++i)
	{
		p10[i]=p10[i-1]*10;
		p9[i]=p9[i-1]*9;
		fact[i]=fact[i-1]*i;
	}
}

long long comb(int N, int K)
{
	if(K<0 || N<K)
		return 0;
	return fact[N]/fact[N-K]/fact[K];
}

int countAtLeast(int cntDig, int K)
{
	if(K<1)
		return p10[cntDig];

	int i, ans=0;

	for(i=K;i<=cntDig;++i)
		ans+=comb(cntDig, i)*p9[cntDig-i];

	return ans;
}

int cnt(int max, int C, int K)
{
	char buf[2][NMAX];
	int i, k, ans=0, len;

	sprintf(buf[0], "%d", max);
	for(i=0;i<NMAX && buf[0][i];++i)
		buf[1][i]='0';
	buf[1][len=i]=0;

	for(k=0;k<NMAX && buf[0][k];++k)
	{
		while(buf[1][k]<buf[0][k])
		{
			ans+=countAtLeast(len-k-1, K-(buf[1][k]=='0'+C));
			++buf[1][k];
		}

		K-=(buf[1][k]=='0'+C);
	}

	if(K<1)
		++ans;

	return ans;
}

int main()
{
	FILE* f=fopen("cifre.in", "r"), *g=fopen("cifre.out", "w");
	int A, B, C, K;

	precalc();

	fscanf(f, "%d%d%d%d", &A, &B, &C, &K);
	fprintf(g, "%.4f\n", (cnt(B, C, K)-cnt(A-1, C, K))/(B-A+1.));

	fclose(f);
	fclose(g);
	return 0;
}