Educational Codeforces Round 8 D. Magic Numbers

Magic Numbers

题意:给定长度不超过2000的a,b;问有多少个x(a<=x<=b)使得x的偶数位为d,奇数位不为d;结果mod 1e9+7;

直接数位DP;注意在判断是否f[pos][mod] != -1之前,要判断是否为边界,否则会出现重复计算;

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MS1(a) memset(a,-1,sizeof(a))
const int N = 2005,MOD = 1e9+7;
char a[N],b[N];
int f[N][N][2],n,m,d;
int dfs(char* s,int p,int mod,int on = 1)
{
    if(p == n) return mod == 0;
    int& ans = f[p][mod][on];
    if(ans != -1) return ans;
    ans = 0;
    for(int i = 0;i <= (on?s[p] - ‘0‘:9);i++){
        if(p%2 && i != d) continue;
        if(p%2 == 0 && i == d) continue;
        (ans += dfs(s,p+1,(mod*10+i)%m,on && i == s[p] - ‘0‘)) %= MOD;
    }
    return ans;
}
int calc(char* s)
{
    MS1(f);
    return dfs(s,0,0);
}
int main()
{
    scanf("%d%d",&m,&d);
    scanf("%s%s",a,b);
    n = strlen(a);
    for(int i = n-1;i >= 0;i--){
        if(a[i] == ‘0‘) a[i] = ‘9‘;
        else{a[i]--;break;}
    }
    printf("%d",(calc(b)-calc(a)+MOD)%MOD);
}

还有一种就是增加一维[2],用来存储是否为边界;大同小异

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MS1(a) memset(a,-1,sizeof(a))
const int N = 2005,MOD = 1e9+7;
char a[N],b[N];
int f[N][N][2],n,m,d;
int dfs(char* s,int p,int mod,int on = 1)
{
    if(p == n) return mod == 0;
    int& ans = f[p][mod][on];
    if(ans != -1) return ans;
    ans = 0;
    for(int i = 0;i <= (on?s[p] - ‘0‘:9);i++){
        if(p%2 && i != d) continue;
        if(p%2 == 0 && i == d) continue;
        (ans += dfs(s,p+1,(mod*10+i)%m,on && i == s[p] - ‘0‘)) %= MOD;
    }
    return ans;
}
int calc(char* s)
{
    MS1(f);
    return dfs(s,0,0);
}
int main()
{
    scanf("%d%d",&m,&d);
    scanf("%s%s",a,b);
    n = strlen(a);
    for(int i = n-1;i >= 0;i--){
        if(a[i] == ‘0‘) a[i] = ‘9‘;
        else{a[i]--;break;}
    }
    printf("%d",(calc(b)-calc(a)+MOD)%MOD);
}

时间: 2024-10-11 22:30:51

Educational Codeforces Round 8 D. Magic Numbers的相关文章

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://codeforces.com/contest/985/problem/E Description Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome w

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars There are n pillars aligned in a row and numbered from 1 to n. Initially each pillar contains exactly one disk. The i-th pillar contains a disk having radius ai. You can move these disks

Educational Codeforces Round 40 C. Matrix Walk( 思维)

Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output There is a matrix A of size x?×?y filled with integers. For every , *A**i,?

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Educational Codeforces Round 26 D. Round Subset(dp)

题目链接:Educational Codeforces Round 26 D. Round Subset 题意: 给你n个数,让你选其中的k个数,使得这k个数的乘积的末尾的0的个数最大. 题解: 显然,末尾乘积0的个数和因子2和因子5的个数有关. 然后考虑dp[i][j]表示选i个数,当前因子5的个数为j时,能得到因子2最多的为多少. 那么对于每个数,记录一下因子2和5的个数,做一些01背包就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) me

CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforces Round 26 题意: 设定数组 y = f(x) 使得 y[i] = sum(x[j]) (0 <= j < i) 求初始数组 A0 经过多少次 f(x) 后 会有一个元素 大于 k 分析: 考虑 A0 = {1, 0, 0, 0} A1 = {1, 1, 1, 1} -> {C(

Educational Codeforces Round 26 D dp,思维

Educational Codeforces Round 26 D. Round Subset 题意:有 n 个数,从中选出 k 个数,要使这 k 个数的乘积末尾的 0 的数量最多. tags:dp好题 dp[i][j][l] 表示前 i 个数,选取了其中 j 个数,分解因子后有 l 个 5时,最多有多少个 2 .i 这一维明显可以省略. 这题一开始有个地方写挫了..选取 j 个数时,应该反着来,即 for( j, k, 1) ,不是 for( j, 1, k) ,不然会多算. #include

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 23 D. Imbalanced Array(单调栈)

题目链接:Educational Codeforces Round 23 D. Imbalanced Array 题意: 给你n个数,定义一个区间的不平衡因子为该区间最大值-最小值. 然后问你这n个数所有的区间的不平衡因子和 题解: 对每一个数算贡献,a[i]的贡献为 当a[i]为最大值时的 a[i]*(i-l+1)*(r-i+1) - 当a[i]为最小值时的a[i]*(i-l+1)*(r-i+1). 计算a[i]的l和r时,用单调栈维护.具体看代码,模拟一下就知道了. 然后把所有的贡献加起来.