Cod sursa(job #65949)

Utilizator VmanDuta Vlad Vman Data 13 iunie 2007 22:11:57
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <stdio.h>
#include <string.h>

long A,B,MAX=1000000000;
int C,K,t[11];
double p;

long numara(long nr)
{
 int l=0,x=0,poz,i,j,min;
 long rez,rezp,tot=0,nr2=nr;
 memset(t,0,sizeof(t));
 while (nr2>0)
       {
	t[++l]=nr2%10;
	nr2/=10;
       }
 poz=1;
 while (nr<MAX)
       {
	//factorial pt combinari
	rezp=1;
	for (i=2;i<=poz-1;++i)
	    rezp*=i;
	//iau pozitia
	x=0;
	for (i=l;i>poz;--i)
		x+=(t[i]==C);
	//apare o cifra in plus
	if (t[poz]<=C)
	   {
	   if (K-x-1>0) min=K-x-1;
	      else min=0;
	   for (i=min;i<=poz-1;++i)
	       {
	       rez=rezp;
	       for (j=2;j<=i;++j)
		   rez/=j;
	       for (j=2;j<=poz-1-i;++j)
		   rez/=j;
	       for (j=1;j<=poz-1-i;++j)
		   rez*=9;
	       tot+=rez;
	       }
	   }
       //calcul normal, fara cifra in plus
	   if (K-x>0) min=K-x;
	      else min=0;
	   for (i=min;i<=poz-1;++i)
	       {
	       rez=rezp;
	       for (j=2;j<=i;++j)
		   rez/=j;
	       for (j=2;j<=poz-1-i;++j)
		   rez/=j;
	       for (j=1;j<=poz-1-i;++j)
		rez*=9;
	       if (t[poz]>C) tot+=(10-t[poz])*rez;
		else tot+=(9-t[poz])*rez;
               }
       //urca o pozitie
       t[poz++]=0;
       ++t[poz];
       while (t[poz]==10)
             {
             t[poz++]=0;
             ++t[poz];
             }
      if (poz>l) l=poz;
      //calculeaza nr
      nr=0;
      for (i=l;i>0;--i)
           nr=nr*10+t[i];
      }
return tot;
}

int main()
{
      freopen("cifre.in","r",stdin);
      scanf("%ld %ld %d %d",&A,&B,&C,&K);
      fclose(stdin);
      freopen("cifre.out","w",stdout);
      p=(double)(numara(A)-numara(B+1))/(B-A+1);
      printf("%.4f",p);
      fclose(stdout);
      return 0;
}