Cod sursa(job #381187)

Utilizator mgntMarius B mgnt Data 9 ianuarie 2010 16:09:15
Problema Cifre Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <iostream>
#include <fstream>
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
}

// Print n with width w.
// PRE: 0<w
// PRE: 0<=n<10**w
void
pw (ostream & os, int n, int w)
{
  if ( 0==n ) {
    while ( 0<w ) {
      os << '0';
      --w;
    }
    return;
  }

  pw(os, n/10, w-1);
  os << "0123456789"[n%10];
}

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*10000);
  os << "0.";
  pw (os, dig4, 4);
  os << endl;
  return 0;
}