Cod sursa(job #756437)

Utilizator matei_cChristescu Matei matei_c Data 9 iunie 2012 17:13:44
Problema Diviz Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.4 kb
#include <cstdio>
#include <cstring>

const int NMAX = 210 ;
const int MOD = 30103 ;

int K, A, B, N;

char a[NMAX];
char aux[NMAX];
int ua[10][NMAX];
int anterior[NMAX][110];
int curent[NMAX][110];

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

	scanf("%d %d %d", &K, &A, &B);
	scanf("%s", a);

	N = strlen(a);

	for (int i = 0; i < N; i++) aux[N - i - 1] = a[i];
	memcpy(a, aux, sizeof(a));

	for (N = 0; a[N]; N++)
		ua[a[N] - '0'][N + 1] = N + 1;

	for (int i = 1; i <= N; i++)
		for (int j = 0; j < 10; j++)
			if (!ua[j][i]) ua[j][i] = ua[j][i - 1];

	int c, mod = 1;

	int rez = 0;

	for (int i = 1; i <= B && i <= N; i++)
	{
		for (int j = i; j <= N; j++)
		{
			c = a[j-1] - '0';

			if (i == 1)
			{
				curent[j][c % K] = 1;
				continue;
			}

			for (int k = 0; k < K; k++)
			{
				for (int cif = 0; cif < 10; cif++)
				{
					if (!ua[cif][j - 1]) continue;
					rest = k - c * mod;
					while (rest < 0) rest += K;

					curent[j][k] += anterior[ ua[cif][j - 1] ][rest];
					if (curent[j][k] >= MOD) curent[j][k] -= MOD;
				}
			}
		}

		if (A <= i)
		{
			for (int j = 1; j < 10; j++)
			{
				if (ua[j][N])
				{ 
					rez += curent[ ua[j][N] ][0];
					if (rez >= MOD) rez -= MOD;
				}
			}
		}

		memcpy(anterior, curent, sizeof(curent));
		memset(curent, 0, sizeof(curent));
		
		mod *= 10; mod %= K;
	}

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

	return 0;
	
}