Magic Numbers CodeForces

来源:互联网 发布:初中试题软件下载 编辑:程序博客网 时间:2024/05/14 10:30

传送门:CodeForces - 628D

题意:定义d-magic数为d出现且只出现在偶数位上。问[l,r]内%m==0的d-magic数有多少个。

思路:一看便知是数位DP,还是很水的那种。。然而蒟蒻并不会。。

坑点:因为是大数,所以边界不能直接-1,可以用字符串模拟大数-1,也可以单独判断一下边界。

代码:

#include<bits/stdc++.h>#define ll long long#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=100010;const int mod=1e9+7;int gcd(int a,int b){return b?gcd(b,a%b):a;}int DP[2200][2200];int DIG[2200];int m,d,len;int    dfs(int pos,int pre,int limit){    if(pos == len)        return    pre==0;    if(!limit && DP[pos][pre] != -1)        return    DP[pos][pre];    int    end = limit ? DIG[pos] : 9;    int    ret = 0;    for(int i = 0;i <= end;i ++)    {    if((pos&1)&&i!=d)continue;    if((!(pos&1))&&i==d)continue;    ret += dfs(pos + 1,(pre*10+i)%m,limit && (i == end)),ret%=mod;}        if(!limit)        DP[pos][pre] = ret;    return    ret;}string l,r;bool check(){int s=0;for(int i=0;i<len;i++){s=s*10+DIG[i];s%=m;if(DIG[i]==d&&(!(i&1)))return false;if(DIG[i]!=d&&(i&1))return false;}return s==0;}int main(){ll ans;std::ios::sync_with_stdio(0);memset(DP,-1,sizeof(DP));cin>>m>>d;cin>>l>>r;len=l.size();for(int i=0;i<len;i++)DIG[i]=l[i]-'0';ans=dfs(0,0,1);ans-=check();len=r.size();for(int i=0;i<len;i++)DIG[i]=r[i]-'0';cout<<(dfs(0,0,1)-ans+mod)%mod; return 0;}


原创粉丝点击