Cod sursa(job #3140079)

Utilizator RolandPetreanPetrean Roland RolandPetrean Data 3 iulie 2023 18:37:57
Problema Cifre Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.26 kb
// https://www.infoarena.ro/problema/cifre
// daca iau iar 20...
#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;
  if (k>n) return 0;

  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] - (v[i] > c));
      dp[i][j][LT] += dp[i-1][j][LT] * 9;
      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=k; i<=n; ++i) ans += dp[n][i][EQ] + dp[n][i][LT];
  return ans;
}

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

  auto da1 = digits(a-1), db = digits(b);

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

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