Cod sursa(job #3140073)

Utilizator RolandPetreanPetrean Roland RolandPetrean Data 3 iulie 2023 18:08:51
Problema Cifre Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.42 kb
// https://www.infoarena.ro/problema/cifre
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

ifstream fin("cifre.in");
ofstream fout("cifre.out");

const int EQ = 0, LT = 1;

int k, c;

int solve(vector<int> v) {
  int n=v.size()-1;

  // dp[i][j][EQ / LT]
  //    - numerele de i cifre mai mici ca v care au j cifre egale cu c
  //    - EQ = numarul e egal cu v[0..i]
  //    - LT = numarul e mai mic ca v[0..i]

  vector<vector<vector<int>>> dp(n+1, vector<vector<int>>(n+1, vector<int>(2)));
  dp[0][0][EQ] = 1;

  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j <= n; ++j) {
      if (j && v[i] == c) dp[i][j][EQ] += dp[i-1][j-1][EQ];
      else if (v[i] != c) dp[i][j][EQ] += dp[i-1][j][EQ];

      dp[i][j][LT] += dp[i-1][j][EQ] * (v[i]-1);
      dp[i][j][LT] += dp[i-1][j][LT] * 10;
      if (j) {
        if (v[i] > c) dp[i][j][LT] += dp[i-1][j-1][EQ];
        dp[i][j][LT] += dp[i-1][j-1][LT];
      }
    }
  }

  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = k; j <= n; ++j) ans += dp[i][j][EQ] + dp[i][j][LT];
  }
  return ans;
}

vector<int> digits(int n) {
  vector<int> d;
  do {
    d.push_back(n%10);
    n /= 10;
  } while (n);
  d.push_back(0);
  reverse(d.begin(), d.end());
  return d;
}
int main() {
  c = 1;
  k = 1;
  int a, b, c, k;
  fin>>a>>b>>c>>k;

  int cnt = solve(digits(b)) - (a ? solve(digits(a - 1)) : 0);
  double ans = (double) cnt / (b-a+1);

  fout<<fixed<<setprecision(10)<<ans;
}