我又来水一发啦。写这个题犯了很多比较傻的错误。。一开始写的等于号我还以为应该是等于等于 就改了 样例还过了 其实就应该是一个等于。。。二维的记忆化竟然被我改成了一维还死活看不出哪错了我真是。。。
还是老套路, pos位置, id标记a还是b ,lim当前位置是否有限制,res余数,st是否是第一个数字。
状态 d[pos][res];
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2024;
const int mod = 1e9 + 7;
char a[maxn],b[maxn],s[maxn];
int m, n, len;
long long d[maxn][maxn];
long long solve(int pos, int id, int lim, int res, int st){
if(pos < 0) return res == 0;
if(!lim && d[pos][res] != -1) return d[pos][res];
int up = 9;
if(lim) up = id ? b[pos] - 48 : a[pos] - 48;
long long ans = 0;
if(!((len - pos)& 1)){
if(up >= n) ans = (ans + solve(pos - 1, id, lim&&up == n, m?(res*10 + n)%m : 0, 1)) % mod;
} else {
for(int i = 0;i <= up;i ++){
if(i == n) continue;
if(st || i) ans = (ans + solve(pos - 1, id, lim&&i == up, m?(res*10 + i)%m : 0, 1)) % mod;
}
}
if(!lim) d[pos][res] = ans;
return ans;
}
int main(){
while(~scanf("%d",&m)){
memset(d, -1, sizeof d);
scanf("%d",&n);
scanf("%s%s",a,b);
len = strlen(b);
reverse(a,a + len);
reverse(b,b + len);
long long ans = solve(len - 1, 1, 1, 0, 0);
if(string(a) == "0") ;
else {
memset(d, -1, sizeof d);
a[0] --;
for(int i = 0;i < len - 1;i ++){
if(a[i] >= 48) break;
a[i] += 10;
a[i + 1] --;
}
if(a[len - 1] == '0') ;
else ans = (ans - solve(len - 1, 0, 1, 0, 0)+ mod) % mod;
}
printf("%I64d\n",ans);
}
return 0;
}