Cod sursa(job #463046)

Utilizator DraStiKDragos Oprica DraStiK Data 14 iunie 2010 14:14:20
Problema Cifre Scor 100
Compilator cpp Status done
Runda preONI Runda 1 Marime 1.4 kb
#include <algorithm>
using namespace std;

#define MAX 100000
#define DIM 5

int cnt[MAX+5],cnt0[MAX+5],fcnt[DIM+5],fcnt0[DIM+5];
int a,b,c,k;

inline int cifre (int x)
{
    int nrc;

    if (!x)
        return 1;
    for (nrc=0; x; x/=10)
        ++nrc;
    return nrc;
}

void init ()
{
    int i;

    scanf ("%d%d%d%d",&a,&b,&c,&k);
    for (i=0; i<MAX; ++i)
    {
        if (i>=10)
        {
            if (i%10==c)
                cnt[i]=cnt[i/10]+1;
            else
                cnt[i]=cnt[i/10];
        }
        else
            if (i%10==c)
                cnt[i]=1;
        cnt0[i]=5-cifre (i)+cnt[i];
        ++fcnt[cnt[i]];
        ++fcnt0[cnt0[i]];
    }
    for (i=5; i; --i)
    {
        fcnt[i-1]+=fcnt[i];
        fcnt0[i-1]+=fcnt0[i];
    }
}

int calc (int x)
{
	int i,nrt,nrc;

	nrt=0;
	for (i=0; i<x/MAX; ++i)
    {
		nrc=max (0,k-cnt[i]);
		if (!c && !i)
			nrt+=fcnt[k];
		else if (!c)
			nrt+=fcnt0[nrc];
		else
            nrt+=fcnt[nrc];
	}
	nrc=max (0,cnt[x/MAX]);
	if (!c && !(x/MAX))
		nrc=0;
	for (i=0; i<=x%MAX; ++i)
		if (c || !i)
		{
			if (nrc+cnt[i]>=k)
				++nrt;
		}
		else if (nrc+cnt0[i]>=k)
			++nrt;
	return nrt;
}

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

    init ();
    printf ("%.4f",(double)(calc (b)-calc (a-1))/(b-a+1));

    return 0;
}