由于科协里最近真的很流行数字游戏,某人又命名了一种取模数,这种数字必须满足各位数字之和 modN 为 0。现在大家又要玩游戏了,指定一个整数闭区间 [a,b],问这个区间内有多少个取模数。
输入格式
题目有多组测试数据。每组只含三个数字 a,b,N。
输出格式
对于每个测试数据输出一行,表示各位数字和 modN 为 0 的数的个数。
样例
Input Output
1 19 9
2
数据范围与提示
对于全部数据,1≤a,b≤231−1,1≤N<100。
取模即使在当前位置上改变余数状态,板子记下来吧
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#define ls (p<<1)
#define rs (p<<1|1)
#define ll long long
using namespace std;
const int maxn = 2e6+5;
const int INF = 0x3f3f3f3f;
ll dp[30][110];//dp[pos][pre]记录了遍历第pos为位时,前一位为pre时的状态数
ll a[30],b[30];
int p;
// void init(){
// dp[0][0]=1;
// dp[0][1]=dp[0][2]=0;
// for(int i=1;i<25;i++){
// dp[i][0]=10*dp[i-1][0]-dp[i-1][1];//长度为i不含有49的个数
// dp[i][1]=dp[i-1][0];//最高位为9但不含49的个数
// dp[i][2]=10*dp[i-1][2]+dp[i-1][1];//含有49的个数
// }
// }
int dfs(int pos,int pre,bool limit) {
if(!pos){
if(pre%p==0)
return 1;
else return 0;
}
if(!limit&&dp[pos][pre]!=-1)
return dp[pos][pre];
int up;
if(limit)
up=a[pos];
else up=9;
int ans=0;
for(int i=0;i<=up;i++) {
ans+=dfs(pos-1,pre+i%p,limit&&i==up);
}
if(!limit)
dp[pos][pre]=ans;
return ans;
}
int init(int n)
{
int len=0;
while(n){
a[++len]=n%10;
n/=10;
}
return dfs(len,0,1);
}
void solve(){
int x,y;
while(scanf("%d%d%d",&x,&y,&p)!=EOF){
memset(dp,-1,sizeof(dp));
cout<<init(y)-init(x-1)<<endl;
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}