Cod sursa(job #756442)

Utilizator matei_cChristescu Matei matei_c Data 9 iunie 2012 17:23:07
Problema Diviz Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.31 kb
#include<cstdio>
#include<cstring>
using namespace std;

#define Nmax 256
#define Kmax 128
#define anterior l%2
#define curent (l-1)%2
#define MOD 30103 

int K,A,B,N;
char s[Nmax];
int next[10][Nmax],sol;
int a[2][Nmax][Kmax];

void prepr()
{
	N=strlen(s);
	for(int i=N-2;i>=0;--i)
	{
	for(int c=0;c<=9;++c)
		if(s[i+1]==c+'0')
			next[c][i+1]=i+2;
		else 
			next[c][i+1]=next[c][i+2];	
		
	}
	for(int i=0;i<=9;++i)
	{
		if(s[0]==i+'0')
			next[i][0]=1;
		else
		next[i][0]=next[i][1];
		if(next[i][0]!=0 && i!=0)
		a[0][next[i][0]][i%K]=1;
	}
}

int main(){
	freopen("diviz.in","r",stdin);
	freopen("diviz.out","w",stdout);
	
	scanf("%d%d%d\n",&K,&A,&B);
	
	fgets(s,Nmax,stdin);
	if(s[strlen(s)-1]=='\n')
		s[strlen(s)-1]='\0';
	prepr();
	if(A==1)
	for(int i=1;i<=N;++i)
	      sol+=a[0][i][0],
		  sol%=MOD;
    
	for(int l=2;l<=B;++l)
	{
		
		memset(a[curent],0,sizeof(a[curent]));
		
		for(int c=0;c<=9;++c)
			for(int rest=0;rest<K;++rest)
				for(int poz=l-1;poz<=N;++poz)
				{
					
				   if(next[c][poz] && a[anterior][poz][rest])
					{
					   
					   a[curent][next[c][poz]][(rest*10+c)%K] += a[anterior][poz][rest];
					   a[curent][next[c][poz]][(rest*10+c)%K] %= MOD;
					}
				}
		if(l>=A)
		for(int i=1;i<=N;++i)
		{	
		    sol += a[curent][i][0] ;
			sol %= MOD ;
		}	  
	}
	
	printf("%d\n",sol);
	return 0;
}