Cod sursa(job #1321558)

Utilizator bghimisFMI Ghimis Bogdan bghimis Data 19 ianuarie 2015 12:01:25
Problema Ratphu Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2014, Anul II Marime 1.43 kb
#include <cstdio>

long long v[1<<17],rez[1<<17][25];
long long d, nrc, m[1<<17][15],f[15],a[15];
char ch;

void makecod()
{
  long long val=0;
  for(int i = 0; i <= 9; ++i)
    {
        m[nrc][i] = a[i];
        val = (long long) val * 100 + a[i];
    }
    v[nrc] = val;
}
void back(int p)
{
    if(p == 10)
    {
        ++nrc;
        makecod();
        return;
    }
    for(int i = 0; i <= f[p]; ++i)
    {
        a[p] = i;
        back(p + 1);
        a[p] = 0;
    }
}

int cautb(long long x)
{
    int i = 0, pas = 1<<18;
    
    for(i = 0; pas; pas >>= 1)
        if(i + pas <= nrc)
            if(v[i + pas] <= x)
                i += pas;
    
    return i;
}

void makemult (int pozc,int restc)
{
  long long codc = 0;
  int pozf;
  for(int i = 0; i <= 9; ++i)
    if(m[pozc][i] < f[i])
      {
	codc = 0;
	for(int j = 0; j <= 9; ++j)
	  if(j != i)
	    codc = codc * 100 + m[pozc][j];
	  else
	    codc=codc*100+m[pozc][j]+1;
	
	pozf = cautb(codc);
	
	for(int j = m[pozc][i] + 1; j <= f[i]; ++j)
	  rez[pozf][(restc * 10 + i) % d] += rez[pozc][restc];
      }
}
int main()
{
  freopen("ratphu.in", "r", stdin);
  freopen("ratphu.out", "w", stdout);
  scanf("%c", &ch);
  
  while(ch!=' ')
    {
      f[ch - '0']++;
      scanf("%c", &ch);
    }
  
  scanf("%lld", &d);
  back(0);
  rez[1][0]=1;
  
  for(int i = 1; i <= nrc; ++i)
    for(int j = 0; j <= d; ++j)
      if(rez[i][j])
	makemult(i, j);
  
  printf("%lld", rez[nrc][0]);
  return 0;
}