Pagini recente » Monitorul de evaluare | Istoria paginii utilizator/pesla | Istoria paginii utilizator/bangalore | Istoria paginii utilizator/cristibarbu | Cod sursa (job #1773856)
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[20][20][2]; //dp[where][K][<]
int nr[20];
int n;
int cnt(int len, int C, int K) {
for (int where = 0; where < len; ++ where)
for (int k = 0; k <= K; ++ k)
if (dp[where][k][0] || dp[where][k][1]) {
for (int digit = (where == 0); digit < 10; ++ digit) {
if (digit < nr[where + 1]) {
dp[where + 1][k + (digit == C)][1] += dp[where][k][0];
dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
}
else if (digit == nr[where + 1]) {
dp[where + 1][k + (digit == C)][0] += dp[where][k][0];
dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
}
else
dp[where + 1][k + (digit == C)][1] += dp[where][k][1];
}
}
int ans = 0;
for (int k = 0; k <= K; ++ k)
ans += dp[len][k][0] + dp[len][k][1];
return ans;
}
int solve(int NR, int C, int K) {
if (NR == -1)
return 0;
if (NR == 0)
return ((C == 0 && K > 0) || C > 0);
n = 0;
while (NR) {
nr[++ n] = NR % 10;
NR /= 10;
}
reverse(nr + 1, nr + n + 1);
int ans = 0;
//Length smaller than n
for (int i = 1; i < n; ++ i) {
memset(dp, 0, sizeof dp);
dp[0][0][1] = 1;
int aux = cnt(i, C, K);
ans += aux;
}
//Length exactly n
memset(dp, 0, sizeof dp);
dp[0][0][0] = 1;
int aux = cnt(n, C, K);
ans += aux;
//0 itself
if ((C == 0 && K > 0) || C > 0)
++ ans;
return ans;
}
int getAns(int A, int B, int C, int K) {
return B - A + 1 - solve(B, C, K - 1) + solve(A - 1, C, K - 1);
}
int main()
{
ifstream cin("cifre.in");
ofstream cout("cifre.out");
int A, B, C, K;
cin >> A >> B >> C >> K;
cout << fixed << setprecision(4) << getAns(A, B, C, K) / (B - A + 1.0) << '\n';
cin.close();
cout.close();
return 0;
}