CodeForces 628D Magic Numbers (数位dp)
题意:找到[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)的更多相关文章
- Educational Codeforces Round 8 D. Magic Numbers 数位DP
D. Magic Numbers 题目连接: http://www.codeforces.com/contest/628/problem/D Description Consider the deci ...
- CodeForces 628 D Magic Numbers 数位DP
Magic Numbers 题意: 题意比较难读:首先对于一个串来说, 如果他是d-串, 那么他的第偶数个字符都是是d,第奇数个字符都不是d. 然后求[L, R]里面的多少个数是d-串,且是m的倍数. ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- 【CF628D】Magic Numbers 数位DP
[CF628D]Magic Numbers 题意:求[a,b]中,偶数位的数字都是d,其余为数字都不是d,且能被m整除的数的个数(这里的偶数位是的是从高位往低位数的偶数位).$a,b<10^{2 ...
- CodeForces - 55D - Beautiful numbers(数位DP,离散化)
链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...
- Codeforces - 55D Beautiful numbers (数位dp+数论)
题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...
- CodeForces - 55D Beautiful numbers —— 数位DP
题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...
- 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 ...
- codeforces628D. Magic Numbers (数位dp)
Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in d ...
随机推荐
- h5-4 canvas
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- oc-24-点语法
/** 点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时, 编译器会自动展开成相应的方法.切记点语法的本质是转换成相应的set和get方法, 如果没有set和get方法,则不能使用点语法. ...
- 设备文件的创建mknod
设备文件是通过mknod命令来创建的.其命令格式为: mknod [OPTION]... NAME TYPE [MAJOR MINOR] TYPE取值: 主设备号和次设备号两个参数合并成一个16位的无 ...
- window.location.Reload()和window.location.href 区别
首先介绍两个方法的语法: reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet])参数: bForceGet, 可选参数, 默认为 false, ...
- 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 4.全局防护Bypass之二次注入
0x01 背景 现在的WEB程序基本都有对SQL注入的全局过滤,像PHP开启了GPC或者在全局文件common.php上使用addslashes()函数对接收的参数进行过滤,尤其是单引号.二次注入也是 ...
- C. Ilya and Sticks
C. Ilya and Sticks time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- SOA资料
实施: 基于J2EE体系架构搭建符合SOA架构的运营管理平台 成功经验: 携程旅行网在SOA架构方面的探索 SOA在互联网系统中的应用
- MySQL(23):事务的隔离级别出现问题之 脏读
1. 脏读 所谓的脏读就是指一个事务读取了另一个事务未提取的数据. 试想一下:a账户要给b账户100元购买商品,如果a账户开启一个事务,执行下面的update语句做了如下转账的工作: update a ...
- css中内容生成器
一,内容生成器:content 补充before和after伪类选择器: 1):将内容添加到某个选择器定义的单个或者多个元素的每一个实例之前或者之后 2)与before选择器配合使用(同理大家想下会不 ...
- 一个Java线程死锁的例子
package com.lk.B; public class Test4 { private static final Object o1 = new Object(); private static ...