题意:找到[a, b]符合下列要求的数的个数。

1、该数字能被m整除

2、该数字奇数位全不为d,偶数位全为d

分析:

1、dp[当前的位数][截止到当前位所形成的数对m取余的结果][当前数位上的数字是否到达了上限]

2、对于第三维的上限,例如一个数字是54362,那么如果前四位是5436,那么前四位都到达了上限,第五位可以从0枚举所有可能,例如如果第五位是1,那么就没到达上限,如果是6就到达了上限,简而言之,就是个匹配的问题。

需要注意的是,上限不是指第二位数字只能是0~4,第三位数字只能是0~3,如果前三位是495,虽然没到达上限,但是也是一种可能的情况

3、枚举余数,截止到某一位所形成的新的数字,是由上一位的余数计算的来,所以加上第i位所形成的有新余数的新数字应该继承前i-1为所形成的有旧余数的数字的情况数

4、大整数取余,从最左位起,设ans = s[i - 1] - '0',分别ans = (ans * 10 + s[i] - '0')% m,计算的结果ans是截止到该位所形成的数字对m取余的结果,由此可知,计算到最右位以后,若该数能被m整除,ans应为0

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) a < b ? a : b
#define Max(a, b) a < b ? b : a
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , -, };
const int dc[] = {-, , , };
const double pi = acos(-1.0);
const double eps = 1e-;
const int MOD = 1e9 + ;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
char a[MAXN], b[MAXN];
int dp[MAXN][MAXN][];
int m, d;
int solve(char *s){//只能计算相同位数范围内的,例如若s=1956,则只计算1000到1956范围内满足条件的
memset(dp, , sizeof dp);
int len = strlen(s);
//初始化第一位
for(int i = ; i < ; ++i){
if(i == d) continue;
if(i < s[] - '') ++dp[][i % m][];
else if(i == s[] - '') ++dp[][i % m][];
}
for(int i = ; i < len; ++i){
if(i & ){//偶数位一定为d
for(int j = ; j < m; ++j){
int tmp = (j * + d) % m;//假设截止到该位所形成的数字为y,而原串截止到该位所形成的数字是5436
(dp[i][tmp][] += dp[i - ][j][]) %= MOD;//y为4989
if(d < s[i] - '') (dp[i][tmp][] += dp[i - ][j][]) %= MOD;//y为5431
else if(d == s[i] - '') (dp[i][tmp][] += dp[i - ][j][]) %= MOD;//y为5436
}
}
else{
for(int j = ; j < ; ++j){//奇数位可能是各种数字,所以枚举
if(j == d) continue;
for(int k = ; k < m; ++k){
int tmp = (k * + j) % m;
(dp[i][tmp][] += dp[i - ][k][]) %= MOD;//分析中第2条的情况,形成的数字由于之前的位都没达到上限,所以这一位的数字无论多大,截止到该位所形成的数字都不会大于上限
if(j < s[i] - '') (dp[i][tmp][] += dp[i - ][k][]) %= MOD;//之前的位到达上限,该位没到达
else if(j == s[i] - '') (dp[i][tmp][] += dp[i - ][k][]) %= MOD;//之前的位到达上限,该位也到达
}
}
}
}
return (dp[len - ][][] + dp[len - ][][]);//只要是截止到len-1位,余数为0的情况都满足,dp[len - 1][0][1]就是s是否满足条件
}
int judge(char *s){//判断该数字是否满足条件
int ans = ;
for(int i = ; s[i]; ++i){
if(i % == && s[i] - '' == d) return ;
if(i & && s[i] - '' != d) return ;
ans = (ans * + s[i] - '') % m;
}
return (ans == ) ? : ;
}
int main(){
scanf("%d%d%s%s", &m, &d, a, b);
int ans = solve(b) - solve(a) + judge(a);//因为solve只能计算相同位数范围内的,因此不能solve(b) - solve(a - 1),假设a为1000,a-1为999
printf("%d\n", (ans + MOD) % MOD);//注意+MOD,因为solve是MOD取余的结果,可能造成solve(b) - solve(a)为负数
return ;
}

CodeForces 628D Magic Numbers (数位dp)的更多相关文章

  1. Educational Codeforces Round 8 D. Magic Numbers 数位DP

    D. Magic Numbers 题目连接: http://www.codeforces.com/contest/628/problem/D Description Consider the deci ...

  2. CodeForces 628 D Magic Numbers 数位DP

    Magic Numbers 题意: 题意比较难读:首先对于一个串来说, 如果他是d-串, 那么他的第偶数个字符都是是d,第奇数个字符都不是d. 然后求[L, R]里面的多少个数是d-串,且是m的倍数. ...

  3. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  4. 【CF628D】Magic Numbers 数位DP

    [CF628D]Magic Numbers 题意:求[a,b]中,偶数位的数字都是d,其余为数字都不是d,且能被m整除的数的个数(这里的偶数位是的是从高位往低位数的偶数位).$a,b<10^{2 ...

  5. CodeForces - 55D - Beautiful numbers(数位DP,离散化)

    链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...

  6. Codeforces - 55D Beautiful numbers (数位dp+数论)

    题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...

  7. CodeForces - 55D Beautiful numbers —— 数位DP

    题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...

  8. Codeforces 628D Magic Numbers

    题意: 求在[a,b](a,b不含前导0)中的d−magic数中有多少个是m的倍数. 分析: 计数dp Let's call a number d-magic if digit d appears i ...

  9. codeforces628D. Magic Numbers (数位dp)

    Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in d ...

随机推荐

  1. 好记心不如烂笔头之JQuery学习,第三章

    第三章中主要讲了几个对DOM进行操作的方法. 归纳如下: 属性的获取和设置: //属性的获取 $("li").attr("title"); //属性的设置 $( ...

  2. cocos2d win7 安卓环境配置开发

    相关工具 下载 Android SDK 下载和安装 Android NDK版本不要选r9的.用r8e!r9会报错 下载安装JDK版本是 jdk-7u13-windows-x64.exe 下载和安装Cy ...

  3. 程序的内存分配 C\C++

    原文:http://blog.csdn.net/oohaha_123/article/details/24460425 程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区( ...

  4. 基于html5实现的愤怒的小鸟网页游戏

    之前给大家分享一款基于html5 canvas和js实现的水果忍者网页版,今天给大家分享一款基于html5实现的愤怒的小鸟网页游戏.这款游戏适用浏览器:360.FireFox.Chrome.Safar ...

  5. Golang学习 - reflect 包

    ------------------------------------------------------------ 在 reflect 包中,主要通过两个函数 TypeOf() 和 ValueO ...

  6. Web安全 之 SQL注入

    随着B/S模式应用开发的发展,使用这种模式编写的应用程序也越来越多.相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据库查询代码,根据 ...

  7. 自定义PopupWindow弹出框(带有动画)

    使用PopupWindow来实现弹出框,并且带有动画效果 首先自定义PopupWindow public class LostPopupWindow extends PopupWindow { pub ...

  8. jQery简单Tab选项卡效果

    简单的Tab效果 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  9. Linux Centos 7 使用yum安装 mysql5.7 (实验成功)

    第一部分:安装Mysql5.7 1.下载YUM库 shell > wget http://dev.mysql.com/get/mysql57-community-release-el7-7.no ...

  10. CF Preparing Olympiad (DFS)

    Preparing Olympiad time limit per test 2 seconds memory limit per test 256 megabytes input standard ...