Cod sursa(job #82595)

Utilizator raula_sanChis Raoul raula_san Data 7 septembrie 2007 20:37:17
Problema Diviz Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <cstdio>
#include <cstring>

#define max_n 201
#define max_k 101
#define max_c 10

#define mod 30103

int k, a, b, m, ret;

short int x[2][max_n][max_k], first[max_c][max_n];

char n[max_n];

void read();
void pp();
void dynamics();
void write();

// first[cif][i] -> prima aparitie a cifrei cif in numarul n dupa pozitia i
// x[i][j][r] -> numarul de subsiruri de lungime i care se termina cu a j - a cifra din numarul n si dau restul r la impartirea cu k

int main()
{
    read();
	pp();
	dynamics();
    write();
    
    return 0;
}

void read()
{
     freopen("diviz.in", "rt", stdin);
     
     scanf("%d %d %d\n", &k, &a, &b);
     gets(n);
     
     m = strlen(n);

	 //

	 char aux[max_n];

	 strcpy(aux, n);
	 n[0] = '#';
	 strcpy(n+1, aux);

	 //


     fclose(stdin);
}

void pp()
{
     int cif, i, p;
     
     for(cif=0; cif<max_c; ++cif)
				for(i=m, p=0; i>=0; --i)
                {
                           if((int) n[i] - '0' == cif)
                           {
									first[cif][i] = p;
									p = i;
						   }
						   else
							   first[cif][i] = p;
                }
}

void dynamics()
{
     int i, j, r, cif;
     
     for(cif=1; cif<max_c; ++cif)
                x[1][first[cif][0]][cif%k] = 1;
     
     for(i=2; i<=b; ++i)
     {
              for(j=1; j<=m; ++j)
                       for(r=0; r<k; ++r)
                                x[i&1][j][r] = 0;
              
              for(j=1; j<=m; ++j)
                       for(r=0; r<k; ++r)
								if(x[(i-1)&1][j][r] > 0)
                                {
                                    for(cif=0; cif<max_c; ++cif)
                                        if(first[cif][j] > 0)
                                        {
											x[i&1][first[cif][j]][(r*10+cif)%k] += x[(i-1)&1][j][r];
                                            x[i&1][first[cif][j]][(r*10+cif)%k] %= mod;
                                        }
                                }
              if(i >= a)
                   for(j=1; j<=m; ++j)
                   {
                       ret += x[i&1][j][0];
                       ret %= mod;
                   }
     }
}

void write()
{
     freopen("diviz.out", "wt", stdout);
     
     printf("%d", ret);
     
     fclose(stdout);
}