Cod sursa(job #332789)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 19 iulie 2009 20:30:23
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.47 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 10;

int A, B, K, cif;
int C[N][N], S[N][N], D[N][N];

void compute()
{
	// init pentru 1
	
	C[0][0] = 1;
	C[1][1] = 1;
	C[1][0] = 8;

	for (int i = 1; i+1 < N; i++)
		for (int j = 0; j <= i; j++)
		{
			C[i+1][j+1] += C[i][j];
			C[i+1][j] += 9 * C[i][j];
		}

	D[0][1] = 1;
	D[1][0] = 9;

	for (int i = 1; i+1 < N; i++)
		for (int j = 0; j <= i; j++) 
		{
			D[i+1][j+1] += D[i][j];
			D[i+1][j] += 9 * D[i][j];
		}

	for (int i = 0; i < N; i++)
	{
		S[i][N-1] = C[i][N-1];
		for (int j = N-2; j >= 0; j--) 
		{
			S[i][j] = S[i][j+1] + C[i][j];
			D[i][j] += D[i][j+1];
		}
	}
}

int calc(int X, int nr, int cif)
{
	int L = 0, res = 0, coef;
	int x[N];

	while (X)
	{
		x[++L] = X % 10;
		X /= 10;
	}

	reverse(x+1, x+L+1);

	if (cif == 0)
		for (int i = 1; i < L; i++) res += D[i][nr];

	for (int i = 1; i <= L; i++)
	{
		coef = 0;

		if (cif < x[i]) 
		{
			if (i > 1 || cif > 0)
			{
				if (nr > 0) 
					for (int j = 0; j <= L-i; j++) res += S[j][nr-1];
				else {
						for (int j = 0; j <= L-i; j++) res += S[j][nr];
			 		 }
			}

			coef = 1;
		}

		for (int j = 0; j <= L-i; j++) res += (x[i]-coef) * S[j][nr];

		if (x[i] == cif && nr > 0) nr--;
	}

	if (nr == 0) res++;

	return res;
}

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

	scanf("%d %d %d %d ", &A, &B, &cif, &K);

	compute();

	printf("%.4lf\n", 1.0 * (calc(B, K, cif) - calc(A-1, K, cif)) / (B-A+1));

	return 0;
}