这道题花了我一个下午的时间才ac,隔壁的@zhangjianjunab 大佬一个小时就切了%%%%%%%
状态定义:f[位数][总和][模数][%完以后剩余的数]
然后求1-x的月之数
从高到低枚举每一位应该填的是,如果这一位x的数字是a[i],那么我们就从0枚举到a[i]-1,直接统计个数。
对于当前填到a[i],我们就不计算,用一个数组存起来,影响以后的统计
#include <cstdio>
#define LL long long
using namespace std;
LL f[11][83][83][83], ten[11];
//f[i][j][x][y] 有i位, 和为j,%x=y 的数的个数
int len, a[11];
LL solve(LL x) {
if (!x) return 0;
len = 0; LL t = x, s = 0;
while (x) {
a[++len] = int(x % 10);
s += a[len];
x /= 10;
}
LL ans = 0;
if (t % s == 0) ans++;
for (int j = 1; j <= 82; j++) {
int sum = j; LL now = 0;
for (int i = len; i >= 1; i--) {
for (int k = 0; k < a[i]; k++)
if (k <= sum)
ans += f[i - 1][sum - k][j][(j - (now + k * ten[i - 1] % j) % j) % j];
sum -= a[i]; if (sum < 0) break;
now = (now + a[i] * ten[i - 1] % j) % j;
}
}
return ans;
}
int main() {
ten[0] = 1; for (int i = 1; i <= 10; i++) ten[i] = ten[i - 1] * 10;
for (int i = 1; i <= 82; i++) f[0][0][i][0] = 1;
for (int i = 1; i <= 10; i++)
for (int j = 0; j <= 82; j++)
for (int x = 1; x <= 82; x++)
for (int y = 0; y < x; y++)
for (int num = 0; num <= 9; num++)
if (num <= j)
f[i][j][x][y] += f[i - 1][j - num][x][(y - num * ten[i - 1] % x + x) % x];
LL x, y;
while (~scanf("%lld%lld", &x, &y))
printf("%lld\n", solve(y) - solve(x - 1));
return 0;
}
tql
%%%%%@zhangjianjunab
只可惜代码没我好看
Orz,YYDSCLB
草(一种植物)