#3878 数字游戏
题面
由于科协里最近真的很流行数字游戏,某人又命名了一种取模数,这种数字必须满足各位数字之和 mod N 为 0 。现在大家又要玩游戏了,指定一个整数闭区间 [a,b],问这个区间内有多少个取模数。
对于全部数据,1≤a,b≤231−1,1≤N<1001≤a,b≤ 2^{31} − 1,1≤N<1001≤a,b≤231−1,1≤N<100
输入
题目有多组测试数据。每组只含三个数字 a,b,N
输出
对于每个测试数据输出一行,表示各位数字和 mod N 为 0 的数的个数。
样例输入
1 19 9
样例输出
2
SOL
设f[i][j][k]f[i][j][k]f[i][j][k]表示iii位数最高位为jjj各位数之和为kkk的合法情况数,然后直接DP就行。
代码
#include<bits/stdc++.h>
using namespace std;
int a,b,n;
int f[15][10][110],h[15];
inline void pre(){
for(int register i=0;i<10;i++)f[1][i][i]=1;
for(int register i=2;i<=10;i++)
for(int register k=0;k<10;k++)
for(int register j=0;j<100;j++)
for(int register t=0;t<10;t++)
f[i][k][j+k]+=f[i-1][t][j];
}
inline int solve(int x){
int register len=0,ans=0,sum=0;
while(x){
h[++len]=x%10;
x/=10;
}
for(int register i=len;i>0;i--){
for(int register j=0;j<h[i];j++){
int maxl=100/n;
for(int register k=1;k<=maxl;k++)
ans+=f[i][j][n*k-sum];
}
sum+=h[i];sum%=n;
if(i==1&&sum%n==0)ans++;
}
return ans;
}
int main(){
pre();
while(scanf("%d%d%d",&a,&b,&n)!=EOF)printf("%d\n",solve(b)-solve(a-1));
return 0;
}