Educational Codeforces Round 8 D - Magic Numbers 数位DP
2016-04-01 08:49
381 查看
题意很简单,偶数位为d,奇数位不为d,且能被m整除的数,叫d-magic,给定d,m,a,b,求在[a,b]上d-magic的个数。
注意 1 既是 0-magic 又是 2/3/4/5/6/7/8/9-magic
还有值得注意的是,给定的a,b 数位相同。 一开始没用到这个条件,写得挺麻烦~
注意 1 既是 0-magic 又是 2/3/4/5/6/7/8/9-magic
还有值得注意的是,给定的a,b 数位相同。 一开始没用到这个条件,写得挺麻烦~
#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<algorithm> #include<ctime> using namespace std; void fre(){freopen("t.txt","r",stdin);} template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; } #define ls o<<1 #define rs o<<1|1 #define MS(x,y) memset(x,y,sizeof(x)) #define debug(x) printf("%d",x); typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; const int INF = 1<<30; const int MAXN = 105; const double eps = 1e-8; const double pi = acos(-1.0); const LL M = 1e9+7; LL dp[2005][2005][2]; int num[2005]; char s[2005]; LL m,d,all; LL dfs(int top, int s, bool e, int flag)//top为第几位数,s为模m的余数,e为是否到上限,flag表示偶数位还是奇数位 { if (top==0) return (s==0 ) ; if (!e && dp[top][s][flag]!=-1) return dp[top][s][flag]; int i; LL res = 0; int u = e?num[top]:9; if(flag) {if(u >= d) res = dfs(top-1,(s*10+d)%m, e&&d==u,flag^1);} else { for (i = 0; i <= u; ++i) { if(i == d) continue;//由于a,b数位相同,所以不用考虑前导0的情况。这里为了代码简单就没改,反正都会减掉的。但是当d = 0 的时候,算出来的并不是 准确的d-magic 个数 res = (res + dfs(top-1, (s*10+i)%m, e&&i==u, flag^1))%M; } } return e?res:dp[top][s][flag]=res; } bool check() { int flag = 1,mo = 0; for(int i = all; i >= 1; --i) { if(!flag && num[i]!=d) return 0; else if(flag && num[i] == d) return 0; mo = ((mo*10)+num[i])%m; flag^=1; } if(mo) return 0; else return 1; } int main() { // fre(); int i; MS(dp,-1); scanf("%I64d%I64d",&m,&d); scanf("%s",s); all = strlen(s); for(i = 0; s[i]; ++i) num[all-i] = s[i]-'0'; LL tem1 = dfs(all,0,1,0); if(check()) tem1-=1; scanf("%s",s); for(i = 0; s[i]; ++i) num[all-i] = s[i]-'0'; LL tem2 = dfs(all,0,1,0); printf("%I64d\n",((tem2 - tem1)%M+M)%M ); }
相关文章推荐
- 每天laravel-20160623|NullStore
- android性能优化
- Java中多线程关于wait()和notify()方法的小错误备忘录
- Make Menuconfig详解 (配置内核选择)
- JS回调函数
- UVA 12299 RMQ with Shifts(线段树+点更新)
- 【三层转七层】——起航篇
- 常见浏览器的兼容问题
- ionic项目中实现发短信和打电话
- Swift_之沙盒与数据存储
- iOS 开发之动画篇 - 从 UIView 动画说起
- ionic项目中实现发短信和打电话
- 重写highlighted改变按钮的按下状态、
- Window7 xp 光驱 显示黄色感叹号
- 复制图层使用实例-创建一个loading效果
- Spring IOC 与AOP
- 为IEnumerable扩展一个ForEach方法
- ionic项目中实现发短信和打电话
- 给层创建一个渐变效果
- 复制图层使用实例01