• 628D Magic Numbers


    传送门

    题目大意

    定义n-magic为从左往右,偶数位置均为n,奇数位置不为n的一类数。求出[a,b]内所有可被m整除的d-magic个数。

    分析

    显然是数位dp,我们用dp[i][j][k]表示考虑到第i位,小于还是等于范围,对m取模的余数为k的时候的个数,然后我们枚举所有满足情况的j(i为奇数则j不能为d,i为偶数则j只能为d)进行转移,转移为经典的数位dp转移。最后记得因为答案取模过所以可能在相减后变为负数因此要进行一下特殊处理。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int mod = 1e9+7;
    int d,M,dp[2100][2][2100],a[2100],cnt,m[2100];
    char s[2100];
    int go(){
          int i,j,k;
          scanf("%s",s);
          cnt=strlen(s);
          m[0]=0;
          for(i=0;i<cnt;i++){
              a[i+1]=(s[i]-'0');
              m[i+1]=(m[i]*10+a[i+1])%M;
          }
          memset(dp,0,sizeof(dp));
          dp[0][0][0]=1;
          for(i=1;i<=cnt;i++){
              for(j=0;j<=a[i];j++){
                if((i&1)&&j==d)continue;
                if(!(i&1)&&j!=d)continue;
                k=m[i-1];
                int x=(k*10+j)%M;
                if(j==a[i])dp[i][0][x]=(dp[i][0][x]+dp[i-1][0][k])%mod;
                else dp[i][1][x]=(dp[i][1][x]+dp[i-1][0][k])%mod;
              }
              for(j=0;j<=9;j++)
                for(k=0;k<M;k++){
                    if((i&1)&&j==d)continue;
                    if(!(i&1)&&j!=d)continue;
                    int x=(k*10+j)%M;
                    dp[i][1][x]=(dp[i][1][x]+dp[i-1][1][k])%mod;
                }
          }
          return (dp[cnt][0][0]+dp[cnt][1][0])%mod;
    }
    int ck(){
          int ok=1,sum=0;
          for(int i=1;i<=cnt;i+=2){
            sum=((sum<<3)+(sum<<1)+a[i])%M;
            if(a[i]==d)return 0;
          }
          for(int i=2;i<=cnt;i+=2){
            sum=((sum<<3)+(sum<<1)+a[i])%M;
            if(a[i]!=d){
              ok=0;
              break;
            }
          }
          if(sum)ok=0;
          return ok;
    }
    int main(){
          scanf("%d%d",&M,&d);
          cout<<abs(go()-ck()-go()-mod)%mod<<endl;
          return 0;
    }
  • 相关阅读:
    Nginx编译安装
    Docker下mysql容器开启binlog日志(保留7天)
    podman
    error: audit:backlog limit exceeded
    64位win2003/win2008系统IIS6.0/7.5配置PHP的方法
    iis7.5安装配置php环境详细清晰教程,三步实现【图文】
    Windows下IIS+PHP 5.2的安装与配置
    无线路由MAC地址过滤安全可靠性讨论
    debian flam3 源码
    debian flam3 依赖文件
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9494087.html
Copyright © 2020-2023  润新知