Cod sursa(job #1390864)

Utilizator ericptsStavarache Petru Eric ericpts Data 17 martie 2015 13:27:24
Problema Diviz Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <fstream>
#include <cstring>
#include <iostream>

using namespace std;

const int MAX_N = 200 + 1;
const int MAX_K = 100 + 1;
const int MOD = 30103;

char s[MAX_N];
int v[MAX_N];

int n, x, a, b;

int DP[2][MAX_N][MAX_K];
int first[10][MAX_N];

int nrm[MAX_K * 10 + 11];

int main() {

    ifstream in("diviz.in");
    in >> x >> a >> b;
    in >> (s + 1);
    n = strlen(s + 1);

    for(int i = 1 ; i <= n ; ++i)
        v[i] = s[i] - '0';

    for(int i = 0 ; i <= 9 ; ++i)
        first[i][n + 1] = (n + 1);

    for(int i = n ; i >= 0 ; --i) {
        for(int c = 0 ; c <= 9 ; ++c) {
            first[c][i] = first[c][i + 1];
        }
        first[v[i]][i] = i;
    }


    for(int k = 0 ; k <= x ; ++k) {
        for(int cif = 0 ; cif <= 9 ; ++cif) {
            int val = k * 10 + cif;
            nrm[val] = val % x;
        }
    }

    for(int i = 1 ; i <= 9 ; ++i)
        DP[1][first[i][0]][i % x] = 1;

    int sol = 0;

    for(int j = 1 ; j <= b ; ++j) {
        int pp = j % 2;

        memset(DP[!pp], 0, sizeof(DP[!pp]));

        for(int i = 1 ; i <= n ; ++i) {
            if(a <= j) {
                sol += DP[pp][i][0];
                if(sol >= MOD)
                    sol -= MOD;
            }
            for(int cif = 0 ; cif <= 9 ; ++cif) {
                if(first[cif][i + 1] > n)
                    continue;
                for(int k = 0 ; k <= x ; ++k) {
                    int nx = k * 10 + cif;
                    nx = nrm[nx];

                    int & val = DP[!pp][first[cif][i + 1]][nx];
                    val += DP[pp][i][k];
                    if(val >= MOD)
                        val -= MOD;
                }

            }
        }
    }

    ofstream out("diviz.out");
    //cout << sol << "\n";
    out << sol << "\n";


    return 0;
}