Cod sursa(job #381109)

Utilizator mgntMarius B mgnt Data 8 ianuarie 2010 23:32:54
Problema Cifre Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

// Given A,B,C,K.
// 0<=A<=B<=1 * 1000 * 1000 * 1000
// 0<=C,K<=9
//
// Count how many numbers in [A..B]
// have at least K digits C, return
// count/(B-A+1) with 4 decimals
// after dot.

int A,B,C,K;

// Returns greatest power of 10 less than
// t.
int
lower10(int t)
{
  int p=1, q;
  while ( ((q=10*p)<t) ) { p=q; }
  return p;
}

// Returns how many elements n in the set
// {0<=n<=t} have at least s digits C in
// their decimal representation.
int
atleast(int t, int s)
{
  // Set {0<=n<t} is empty.
  if ( 0 >t ) { return 0; }

  // Each element of set {0<=n<=t} has at least 0
  // digits C.
  if ( 0==s ) { return 1+t; }

  // t is representable by a single digit.
  if ( t<10 ) { return (C<=t)?(1):(0); }


  // z is the greatest power of 10 less than t.  
  int z=lower10(t), ct=0, i, r=t%z;

  // t=54321
  //   4xyzt 
  //   3zyzt
  //   2zyzt
  //   1zyzt
  //   0zyzt
  //   4321
  // Cut the first digit, and deal with
  // all possibilities in last digits, and
  // also treat the remainder.
  ct += atleast(z-1,s); // 0xyzt ... zyzt (0 is not accounted on first pos)
  for ( i=1; i*z+r<t; ++i ) {
    ct += atleast(z-1,s-(C==i)?(1):(0)); // ixyzt , i=1..4 (in e.g. above)
  }
  ct += atleast(t%z,s-(C==t/z)?(1):(0));
  return ct; // return count
}

int
main ( )
{
  ifstream is("cifre.in");
  ofstream os("cifre.out");
  is >> A >> B >> C >> K;
  int count = atleast(B,K)-atleast(A-1,K);
  double ans= ((double)count)/(B-A+1);
  // output ans with 4 digit precision ... and accuracy
  int dig4 = (int)((ans+0.00005)*10000);
  os << "0." << dig4 << endl;
  return 0;
}