# [BZOJ4467] [JSOI2013]数字理论

1. D10K1x<D10K$D*10^{K-1}\le x
2. x mod D=0$x~mod~D=0$
3. digit(x)=P  //digit(x)x$digit(x)=P~~//digit(x)是x的各个数位数字之和$
4. digit(x/D)=S$digit(x/D)=S$

bool dp[len][sum1][sum2][res]意思是，有一个数W，digit(W div D)=sum1,digit(W)=sum2,W mod D=res，能否通过在W的末尾加len位数字使得符合要求

#include <cstdio>
#include <assert.h>
int K, S, P, D;
bool dp[100][901][102][9];
int main()
{
scanf("%d%d%d%d", &K, &S, &P, &D);
if (S > K * 9 || P > K * 9)
return puts("-1"), 0;
if (S * D % 9 != P % 9)
return puts("-1"), 0;
dp[0][S][P / 9][0] = 1;
for (int i = 1; i < K; i++)
{
int S_low = S - i * 9, P_low = P - i * 9, MODnine;
if (S_low < 0)
S_low = 0;
if (P_low < 0)
P_low = 0;
for (int j = S_low; j <= S; j++)
{
bool (*DP)[9] = dp[i][j];
for (int l = 0; l < D; l++)
{
MODnine = (j * D + l) % 9;
for (int k = P_low / 9, realk = k * 9 + MODnine; realk <= P; k++, realk += 9)
for (int di = 0; !DP[k][l] && di < 10; di++)
if (dp[i - 1][j + (l * 10 + di) / D][(realk + di) / 9][(l * 10 + di) % D])
DP[k][l] = 1;
}
}
}
if (head == 10 * D)
puts("-1");
else
{
int res = head % D;
int I = K - 1, J = head / D, K = head / 10 + head % 10, L = head % D, di;
int newI, newJ, newK, newL;
while (I)
{
for (di = 0; !dp[I - 1][J + (L * 10 + di) / D][(K + di) / 9][(L * 10 + di) % D]; di++)
"Nothing to do..";
putchar((res * 10 + di) / D + 48);
res = (res * 10 + di) % D;
newI = I - 1, newJ = J + (L * 10 + di) / D, newK = K + di, newL = (L * 10 + di) % D;
I = newI, J = newJ, K = newK, L = newL;
}
assert(res == 0);
}
return 0;
}