Cod sursa(job #1941258)

Utilizator BugirosRobert Bugiros Data 27 martie 2017 09:07:09
Problema Diviz Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <fstream>
using namespace std;

ifstream in("diviz.in");
ofstream out("diviz.out");

const int MAXNRCIF = 203;
const int MAXK = 103;
const int MODULO = 30103;

int k, a, b;
int v[MAXNRCIF];
int n;

void citire()
{
    in >> k >> a >> b;
    char sir[MAXNRCIF] = {0};
    in >> sir;
    for (int i = 0;sir[i] != 0;++i)
    {
        v[i + 1] = sir[i] - '0';
        ++n;
    }
}

//d[l][i][r] - numarul de moduri de a alege subsiruri distincte
//             de lungime l, cu ultima cifra cea de pe pozitia i in n
//             subsiruri ce dau restul r la impartirea cu K
int d[2][MAXNRCIF][MAXK];

//p[cif][i] - prima aparitia a cifrei cif dupa pozitia i in n
int p[10][MAXNRCIF];

int rasp = 0;

void calculare_p()
{
    for (int cif = 0;cif <= 9;++cif)
        for (int i = n;i >= 1;--i)
            if (v[i] == cif)
                p[cif][i] = i;
            else p[cif][i] = p[cif][i + 1];
}

void dinamica()
{
    for (int cif = 1;cif <= 9;++cif)
        d[1][p[cif][1]][cif % k] = 1;

    for (int l = 1;l <= b;++l)
        for (int i = l;i <= n;++i)
        {
            for (int r = 0;r < k;++r)
            {
                if (d[l % 2][i][r] == 0)
                    continue;

                for (int cif = 0;cif <= 9;++cif)
                    if (p[cif][i + 1] != 0)
                    {
                        int &nr = d[(l + 1) % 2][p[cif][i + 1]][(r * 10 + cif) % k];
                        nr = (nr + d[l % 2][i][r]) % MODULO;
                    }
                if (r != 0)//curatare rand (0 ne trebuie pentru solutie)
                    d[l % 2][i][r] = 0;
            }
            if (l >= a)
                rasp = (rasp + d[l % 2][i][0]) % MODULO;
            d[l % 2][i][0] = 0;//acum putem curata si 0
        }
}

int main()
{
    citire();
    calculare_p();
    dinamica();
    out << rasp << '\n';
    return 0;
}