codeforces628DMagic Numbers

来源:互联网 发布:手机自动充电软件 编辑:程序博客网 时间:2024/06/18 13:31

Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in decimal presentation of the number on even positions and nowhere else.

For example, the numbers 1727374171 are 7-magic but 7771233471 are not 7-magic. On the other hand the number 7 is 0-magic123 is 2-magic34 is 4-magicand 71 is 1-magic.

Find the number of d-magic numbers in the segment [a, b] that are multiple of m. Because the answer can be very huge you should only find its value modulo 109 + 7 (so you should find the remainder after dividing by 109 + 7).

Input

The first line contains two integers m, d (1 ≤ m ≤ 20000 ≤ d ≤ 9) — the parameters from the problem statement.

The second line contains positive integer a in decimal presentation (without leading zeroes).

The third line contains positive integer b in decimal presentation (without leading zeroes).

It is guaranteed that a ≤ b, the number of digits in a and b are the same and don't exceed 2000.

Output

Print the only integer a — the remainder after dividing by 109 + 7 of the number of d-magic numbers in segment [a, b] that are multiple of m.


分析:这是一道数位DP题。数位DP题的基本特性是给你两个数,然后在这两个数字之间找到符合约束条件的数的个数,

数位DP有一个模板可以用于套,那么问题的解决就在于DP的过程中对符合条件的数进行筛选,这一题是简单题,DP过

程加个IF语句就可以了。

然后来讲讲在DFS的三个参数值那个jud在算法中的运用,jug=1时表示此时数字是满位,例如考虑数字3的时候,当我对

0,1,2,进行求值的时候,jug就为0了。

jug的值在算法中的记忆化搜索有着重要的地位,为什么在jug=0时可以直接返回dp值而jug=1的时候不可以呢?.主要是

当jug为零的时候是枚举0-9的,而jug=1的是时候只枚举下一位m(0-m),如果在jug=1时也直接返回状态会变多进而

导致答案也比所求答案大,那么就不正确了。

#include<bits/stdc++.h>using namespace std;const int maxn=2100;typedef long long LL;int num[maxn],len;LL dp[maxn][maxn];const int MOD=1e9+7;char ax[maxn],bx[maxn];int m,d;LL dfs(int pos,int ok,int jud){     if(pos==len)return ok==0;     if(!jud&&dp[pos][ok]!=-1)return dp[pos][ok];     LL ans=0;     int sz=jud?num[pos]:9;     for(int i=0;i<=sz;i++)     {         if(pos%2==0&&i==d)continue;         if(pos%2!=0&&i!=d)continue;         ans+=dfs(pos+1,(ok*10+i)%m,jud&&(sz==i));         ans%=MOD;     }     if(!jud)        dp[pos][ok]=ans;     return ans;}LL Cou(char* s){    int pos=0;    for(int i=0;i<len;i++)    {        int index=s[i]-'0';        num[i]=index;    }    return dfs(0,0,1);}int jud(char* s){    int temp=0;    for(int i=0;i<len;i++)    {        num[i]=s[i]-'0';        if(num[i]==d&&i%2==0)            return 0;        if(num[i]!=d&&i%2==1)            return 0;        temp=(temp*10+num[i])%m;    }    return temp==0;}int main(){    memset(dp,-1,sizeof(dp));    scanf("%d%d",&m,&d);    scanf("%s%s",&ax,&bx);    len=strlen(ax);    //cout<<Cou(ax)<<endl;    printf("%d",(Cou(bx)%MOD-Cou(ax)%MOD+jud(ax)+MOD)%MOD);    return 0;}