Pagini recente » Cod sursa (job #2536732) | Cod sursa (job #656965) | Cod sursa (job #843916) | Cod sursa (job #3235200) | Cod sursa (job #842028)
Cod sursa(job #842028)
/* Problema se rezolva prin metoda programarii dinamice.
Fie P[j][i][r] numarul de moduri de a alege subsiruri distincte de lungime j care contin ca ultima cifra cea de-a i-a cifra a numarului N,
subsiruri care sa dea restul r la impartirea K. Daca ne aflam in starea (j, i, r) putem sa actualizam starea (j+1, first[cif][i+1], (r*10+cif) mod K),
considerand ca am adaugat la sfarsitul fiecarui subsir definit de (j, i, r) cifra cif. Prin first[cif][i] se defineste prima aparitie in numarul N a cifrei cif dupa pozitia i. Tabloul first va fi, evident, preprocesat. Pentru a nu numara subsirurile egale de doua ori, trebuie sa initializam pentru lungimea 1 doar pozitiile care contin pentru prima oara o cifra. Astfel initializam starile (1, first[cif][0], cif mod K) cu 1, pentru cif = 1..9 (ca nu cumva un subsir sa inceapa cu 0). Pe parcurs, adunam la solutie starile care au lungimea cuprinsa intre A si B si care au r egal cu 0.
Complexitatea finala a algoritmului este O(K * L2), unde L este numarul de cifre ale numarului N.
*/
#include <cstring>
#include <fstream>
using namespace std;
ifstream f("diviz.in"); ofstream g("diviz.out");
const int MOD = 30103;
int K, A, B, nr;
char N[202];
int P[2][202][102];
int last[10],x[202];
int main()
{
f >> K >> A >> B >> N;
int M = strlen(N);
for (int i = 1; i <= M; ++i) x[i]=N[i-1]-'0';
int act = 0;
for (int i = 1; i <= M; ++i) // cu i cifre
{
act = !act;
memset(P[act], 0, sizeof(P[act]));
for (int j = 1; j <= M; ++j) // se termina pana in j
{
if (i == 1 && x[j]) P[act][j][x[j] % K] = 1;
for (int r = 0; r < K; ++r) // cel dinainte avea restul r
{
P[act][j][(r * 10 + x[j]) % K] += P[!act][j - 1][r];
if (P[act][j][(r * 10 + x[j]) % K] >= MOD) P[act][j][(r * 10 + x[j]) % K] -= MOD;
}
}
for (int r = 0; r < K; ++r)
{
memset(last, 0, sizeof(last));
for (int j = 1; j <= M; ++j)
{
P[act][j][r] -= last[x[j]];
last[x[j]] = P[act][j][r] + last[x[j]];
P[act][j][r] += P[act][j - 1][r];
while (P[act][j][r] >= MOD) P[act][j][r] -= MOD;
while (P[act][j][r] < 0) P[act][j][r] += MOD;
}
}
if (i >= A && i <= B)
{
nr += P[act][M][0];
if (nr >= MOD) nr -= MOD;
}
}
g << nr << '\n';
g.close();
return 0;
}