Cod sursa(job #1551383)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 15 decembrie 2015 20:03:24
Problema Cifre Scor 60
Compilator c Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

#define MAX_N 13
#define SMECHERIE 1000000

int dig, freq;

int D[MAX_N][MAX_N];

int memo( int N, int f ) {
  if ( N < 0 ) {
    return 0;
  }

  if ( D[N][f] != -1 ) {
    return D[N][f];
  }

  if ( N == 0 ) {
    return D[N][f] = ( f >= freq );
  }

  int i, q;

  q = 0;
  for ( i = 0; i < 10; i++ ) {
    q += memo( N - 1, f + ( dig == i ) );
  }
  D[N][f] = q;

  return q;
}

int DP( int X ) {
  char buf[MAX_N];
  int N, i, j, currDig, q, fr;

  for ( i = 0; i < MAX_N; i++ )
    for ( j = 0; j < MAX_N; j++ )
      D[i][j] = -1;

  sprintf( buf, "%d", X );
  N = strlen( buf );

  q = fr = 0;

  for ( i = 0; i < N; i++ ) {
    currDig = buf[i] - '0';
    for ( j = 0; j < currDig; j++ )
      q += memo( N - i - 1, fr + ( dig == j ) );
    fr += ( currDig == dig );
  }
  return q;
}

int main(void) {
  FILE *fin, *fout;
  int A, B, i, j, tmp, t;
  int numarator, numitor;

  fin = fopen( "cifre.in", "r" );
  fscanf( fin, "%d%d%d%d", &A, &B, &dig, &freq );
  fclose( fin );

  fout = fopen( "cifre.out", "w" );

  if ( freq == 0 ) {
    numarator = numitor = 1;
  } else {
    if ( dig == 0 ) {
      numarator = 0;
      if ( B - A + 1 <= SMECHERIE ) {
        numitor = B - A + 1;
        for ( t = A; t <= B; t++ ) {
          tmp = t;
          i = tmp / 10;
          j = 0;
          do {
            j += ( tmp - ( i << 1 ) - ( i << 3 ) == dig );
            tmp = i;
            i = tmp / 10;
          } while ( (tmp > 0) && (j != freq) );
          numarator += ( j == freq );
        }
      } else {
        numitor = SMECHERIE;
        srand(time(NULL));
        for ( i = 0; i < SMECHERIE; i++ ) {
          tmp = rand() % (B-A+1) + A;
          i = tmp / 10;
          j = 0;
          do {
            j += ( tmp - ( i << 1 ) - ( i << 3 ) == dig );
            tmp = i;
            i = tmp / 10;
          } while ( (tmp > 0) && (j != freq) );
          numarator += ( j == freq );
        }
      }
    } else {
      numarator = DP(B+1) - DP(A);
      numitor = B - A + 1;
    }
    fprintf( fout, "%.4f\n", 1.00 * numarator / numitor );
  }
  fclose( fout );
  return 0;
}