Cod sursa(job #53037)

Utilizator moga_florianFlorian MOGA moga_florian Data 20 aprilie 2007 18:54:11
Problema Cifre Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.65 kb
#include<stdio.h>

int C,K;
int a[15],n,b[15];
int p9[15];

int valid(int conf)
{
int nr=0,i;
for(i=0;i<n;i++)
  if( ((1<<i) & conf) )
     nr++;
     
if(nr>=K)
  return 1;
return 0;    
}

int maimare()
{
int i=n;
while(i && a[i]==b[i]) i--;
if(i && b[i]>a[i])
   return 1;
return 0;
}

int f(int x)
{
int varza=x,conf,k,tot=0,i,sum,nr0;   

n=0;
while(varza)
 {
 a[++n]=varza%10;
 varza/=10;        
 }
 
//cate de lungime 1,...,n-1 exista
if(n-1>0 && n-1-K>=0)
  {
  for(i=0;i<(1<<(n-1));i++)
     if(valid(i))
       {
       nr0=0;
       for(k=0;k<n-1;k++)
          if( ((1<<k) & i)==0)
             nr0++;
             
       tot+=p9[nr0];                           
       }     
  }

//de lungime n
for(conf=0;conf<(1<<(n));conf++)
 if(valid(conf))
  {
  sum=0;
  //constructie b
  for(i=1;i<=n;i++)
    if( ((1<<(i-1)) & conf) )
       b[i]=C;
    else
       b[i]=0;
       
  if(b[n]==0)
     b[n]=1;
     
  if(maimare()==0)
    {
    nr0=0;
    for(i=n;i;i--)
       if( ((1<<(i-1))&conf)==0 )
          {
          nr0++;
          k=0;
          while(k<=9 && maimare()==0)
            {
            k++;
            if(k==C)
              k++;
            b[i]=k;                             
            }
          b[i]--;                                          
          if(b[i]==C)
            b[i]--;
          }        
          
    i=1;
    while(i<=n && a[i]>=0) i++;
                         
    if(i>n && b[n])
    {
    for(k=n;k;k--)
      if( ((1<<(k-1)) & conf)==0 )
       {
       nr0--;
       
       if(k==n)
         {
         if(b[k]>C)
            sum+=(b[k]-2)*p9[nr0];
         else
            sum+=(b[k]-1)*p9[nr0];
         }
       else
         {
         if(b[k]>C)
            sum+=(b[k]-1)*p9[nr0];
         else
            sum+=b[k]*p9[nr0];               
         }                 
       }
    sum++;
      
    tot+=sum;
    }
    }
  }
return tot;
}

int f0(int x)
{
int varza=x,i,conf,tot=0,sum,n0,k;

n=0;
while(varza)
  {
  a[++n]=varza%10;
  varza/=10;
  }   
  
//de lungime 1,n-1
k=2;
while(n-k>=0 && n-k-K>=0)
   {
   for(conf=0;conf<(1<<(n-k));conf++)    
     {
     n0=0;
     for(i=0;i<n-k;i++)
       if( ((1<<i) & conf)==0 )
         n0++;
         
     if(n-k-n0 >= K)
         tot+=p9[n0+1];
     }
   k++;
   }
     
//de lungime n
for(conf=0;conf< (1<<(n-1)); conf++)
  {
  sum=0;
  n0=0;
  for(i=0;i<n-1;i++)
    if( ((1<<i) & conf)==0 )
       n0++;
               
  if(n-1-n0 >= K)
    {
    //constructie b
    for(i=0;i<n-1;i++)
      if( ((1<<i) & conf) )
         b[i+1]=0;
      else
         b[i+1]=1;
    b[n]=1;
    
    if(maimare()==0)
      {
      for(i=n;i;i--)
        if(b[i])
         {
         k=1;
         while(k<=9 && maimare()==0)
            {
            k++;
            b[i]=k;        
            }
         b[i]--;
         }
      n0++;
         
      for(i=n;i;i--)
        if(b[i])
          {
          n0--;
          
          sum+=(b[i]-1)*p9[n0];          
          }
      sum++;
        
      tot+=sum;                    
      }            
    }  
  }
return tot;
}

int main()
{
FILE *fin=fopen("cifre.in","r"),
     *fout=fopen("cifre.out","w");
     
int A,B,i;
fscanf(fin,"%d%d%d%d",&A,&B,&C,&K);

p9[0]=1;
for(i=1;i<=12;i++)
  p9[i]=p9[i-1]*9;

int nr,nr2;

if(C)
{
nr=f(B);
nr2=f(A-1);
nr-=nr2;
}
else
{
nr=f0(B);
nr2=f0(A-1);
nr-=nr2;    
}

double sol=(double)nr / (double)(B-A+1);
fprintf(fout,"%.4f\n",sol);

fclose(fin);
fclose(fout);
return 0;    
}