Cod sursa(job #82632)

Utilizator raula_sanChis Raoul raula_san Data 7 septembrie 2007 22:33:55
Problema Diviz Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <cstdio>
#include <cstring>

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

int k, a, b, m, ret;

int x[2][max_n][max_k], first[max_c][max_n], 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);

	 int i; char c;

	 for(i=1; ; ++i)
	 {
		scanf("%c", &c);

		if(c >= '0' && c <= '9')
			n[++m] = (int) (c - '0');

		else
			break;
	 }

     fclose(stdin);
}

void pp()
{
     int cif, i, p;
     
     for(cif=0; cif<max_c; ++cif)
				for(i=m, p=0; i>=0; --i)
                {
						   if(n[i] == 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)
		if(first[cif][0] > 0)
				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] %= 30103;
										}
								}
			  if(i >= a)
				   for(j=1; j<=m; ++j)
				   {
					   ret += x[i&1][j][0];
					   ret %= 30103;
                   }
     }
*/

     for(cif=1; cif<max_c; ++cif)
                if(first[cif][0])
                {
                           x[1][first[cif][0]][cif%k] = 1;
                           ++ r;
                }
                
     for(i=1; i<b; ++i)
     {
              for(j=1; j<=m; ++j)
                       for(r=0; r<k; ++r)
                                x[(i+1)&1][j][r] = 0;
                                
              for(j=1; j<=m; ++j)
                       for(r=0; r<k; ++r)
                                if(x[i&1][j][r])
                                {
                                    for(cif=0; cif<9; ++cif)
                                        if(first[cif][j])
                                        {
                                                         x[(i+1)&1][first[cif][j]][((r*10)+cif)%k] += x[i&1][j][r];
                                                         x[(i+1)&1][first[cif][j]][((r*10)+cif)%k] %= 30103;
                                        }
                                }
                                
              if((i + 1) >= a)
                    for(j=1; j<=m; ++j)
                    {
                             ret += x[(i+1)&1][j][0];
                             ret %= 30103;
                    }
     }
}

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