Cod sursa(job #1090257)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 22 ianuarie 2014 15:20:27
Problema Diviz Scor 0
Compilator cpp Status done
Runda concurs_2014 Marime 1.46 kb
#include <cstdio>
#include <cstring>

#define Nmax 105
#define MOD 30103

using namespace std;

int K,A,B,N;
int DP[Nmax][Nmax][Nmax];

char s[Nmax];

void euclid(long long a,long long b,long long &x,long long &y)
{
    if(!b)
    {
        x = 1;
        y = 0;
        return;
    }
    long long x1,y1;
    euclid(b,a%b,x1,y1);
    x = y1;
    y = x1 - y1*(a/b);
}

void read()
{
    scanf("%d%d%d\n%s",&K,&A,&B,s+1);
    s[0] ='*';
    N = strlen(s) - 1;
}

int F(int lung ,int ends ,int rest) /// lungime,unde se termina si au rest restul
{
    if(DP[lung][ends][rest] != -1)
        return DP[lung][ends][rest];

    if(lung == 1)
    {
        DP[lung][ends][rest] = ((s[ends]-48) % K == 0 );
        return DP[lung][ends][rest];
    }
    int val = 0;
    long long x,y;

    for(int i  = lung-1; i < ends; ++i)
    {
        euclid(rest-(s[ends]-48) ,K,x,y);
        val = (val + F(lung - 1 , i , (x + K) % K ) ) % MOD;
    }
    DP[lung][ends][rest] = val;
    return DP[lung][ends][rest];
}

int main()
{
    freopen("diviz.in","r",stdin);
    freopen("diviz.out","w",stdout);

    for(int i = 0;i <= 101; ++i)
        for(int j = 0 ; j <= 101; ++j)
            for(int k = 0 ; k <= 101; ++k)
                DP[i][j][k] = -1;

    read();
    int ans = 0;
    for(int i = A; i <= B; ++i)
        for(int j = i; j <= N; ++j)
            ans = (ans + F(i,j,0)) % MOD;

    printf("%d\n",ans);

    return 0;
}