[当前位数][之前每一位的和][当前余数][当前位数字是否与原数相同]
打表
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10;
int f[N*N][N][N*N][N*N],power[10];
int n=9,m=81, num[10];
int ask(int x)
{
int res = 0, d = 0;
for(int t=x; t; t/=10) d++;
for(int i=1; i<=d; i++) num[i] = x % 10, x /= 10;
for(int sum=1; sum<=d*9; sum++) { // 枚举数位之和
int nowsum = 0, nowx = 0;
for(int i=d; i>=1; i--) { // 选到第几位
for(int j=0; (i == 1 ? j <= num[i] : j < num[i]) && sum - nowsum - j >= 0; j++)
res += f[sum][i-1][sum-nowsum-j][(sum-(nowx+j*power[i-1])%sum+sum)%sum];
nowsum += num[i], nowx = (nowx + num[i] * power[i-1]) % sum;
}
}
return res;
}
int main()
{
power[0] = 1;
for(int i=1;i<=n;i++)power[i] = power[i-1] * 10;
for(int mod=1;mod<=m;mod++)
{
f[mod][0][0][0] = 1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
for(int k=0;k<mod;k++)
{
for(int p=0;p<=n &&p <= j;p++)
{
f[mod][i][j][k]+=f[mod][i-1][j-p][(k-p*power[i-1]%mod+mod)%mod];
}
}
}
}
}
int l,r;
while(cin >> l >> r){ cout<<ask(r) - ask(l-1); }
}

京公网安备 11010502036488号