Cod sursa(job #7470)

Utilizator astronomyAirinei Adrian astronomy Data 21 ianuarie 2007 16:04:42
Problema Diviz Scor 20
Compilator c Status done
Runda Arhiva de probleme Marime 2.35 kb
#include <stdio.h>
#include <string.h>

#define MAX_N 202
#define MAX_K 101
#define MOD 30103

int N, K, A, B, X[MAX_N];
int cnt[2][10][MAX_N][MAX_K];
int res;

int mod[1<<14], p[16];
int modK;

void preproc(void)
{
    int i;
    for(i = 0; i < 16000; i++)
        mod[i] = i % K;
    for(p[0] = 1, i = 1; i <= 8; i++)
        p[i] = p[i-1]*10;
}

int getrest(int x, int z)
{
    int i, t, c, r;
    if(z <= 8)
    {
        x = p[z];
        return x % K;
    }
    for(i = 1; i <= 8; i++)
        x *= 10;
    r = x % K, t = (z-8)>>3, c = (z-8)&7;
    for(i = 1; i <= t; i++)
        r = r*modK, r = mod[r];
    t = p[c];
    r = r*(t%K), r = mod[r];
    return r;
}

void solve(void)
{
    int u, v, i, j, r, c, t, rp, rnou;

    u = 0, v = 1;

    preproc();
    modK = 100000000%K;
    
    for(i = N; i >= 1; i--)
    {
        for(j = 1; j <= (N-i+1); j++)
         for(r = 0; r < K; r++)
          for(c = 0; c <= 9; c++)
           if(c == X[i])
           {
                if(j == 1)
                {
                    if(r == mod[c])
                        cnt[v][c][j][r] = 1;
                    continue ;
                }
                else
                {
                    rp = getrest(X[i], j-1), rnou = mod[r-rp+K];
                    cnt[v][c][j][r] = 0;
                    for(t = 0; t <= 9; t++)
                    {
                        cnt[v][c][j][r] += cnt[u][t][j-1][rnou];
                        if(cnt[v][c][j][r] >= MOD)
                            cnt[v][c][j][r] -= MOD;
                    }
                }
           }
           else
           {
                cnt[v][c][j][r] = cnt[u][c][j][r];
           }
        u ^= 1, v ^= 1;
    }

    for(c = 1; c <= 9; c++)
     for(j = A; j <= B; j++)
     {
        res += cnt[u][c][j][0];
        if(res >= MOD)
            res -= MOD;
     }
}

void read_data(void)
{
    int i;
    char sir[1024];

    scanf("%d %d %d\n", &K, &A, &B);

    scanf("%s\n", &sir), N = strlen(sir);
    for(i = 1; i <= N; i++)
        X[i] = sir[i-1]-48;
}

void write_data(void)
{
    printf("%d\n", res);
}

int main(void)
{
    freopen("diviz.in", "rt", stdin);
    freopen("diviz.out", "wt", stdout);

    read_data();
    solve();
    write_data();

    return 0;
}