hdu 2089 不要62 (数位DP)
2016-04-24 09:13
246 查看
不要62
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 31185 Accepted Submission(s): 11017
[align=left]Problem Description[/align]
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
[align=left]Input[/align]
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
[align=left]Output[/align]
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
[align=left]Sample Input[/align]
1 100 0 0
[align=left]Sample Output[/align]
80
[align=left]Author[/align]
qianneng
[align=left]Source[/align]
迎接新学期——超级Easy版热身赛
[align=left]Recommend[/align]
lcy | We have carefully selected several similar problems for you: 2094 2090 2091 2093 2092
Statistic | Submit | Discuss
|
Note
题解:数位DP
具体过程参见代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> using namespace std; int n,m,cnt,num[10]; int dp[12][12]; int sqr(int x,int y) { int t=1; if (y==0) return 1; for (int i=1;i<=y;i++) t=t*10; return t; } int sqr1(int x,int y) { int t=0; for (int i=1;i<=y;i++) t=t*10+9; return t; } void init() { dp[0][0]=1; for (int i=1;i<=7;i++) { dp[i][0]=9*dp[i-1][0]-dp[i-1][1]; //dp[i][0] 表示位数不超过i的数字中不含不吉利的数字个数 dp[i][1]=dp[i-1][0];//dp[i][1] 表示位数不超过i的数字中不含不吉利数字,且最高位为2的个数 dp[i][2]=sqr1(9,i)+1-dp[i][0];//dp[i][2] 表示位数不超过i的数字中含不吉利数字的个数 } } int solve(int x) { int ans=0,k=x; cnt=0; int tot=0; while (x) //把数字按位分解 { num[++tot]=x%10; x/=10; } bool f=false; num[0]=0; num[tot+1]=0; for (int i=tot;i>=1;i--) //计算的时候,把数拆分,例如43,拆成1-39,40-43来计算 { if (f) { continue; } if (num[i]<4) ans+=(num[i])*dp[i-1][2]; //当前位小于4,直接计算0-(num[i]-1) else if (num[i]>4) ans+=sqr(10,i-1)+(num[i]-1)*dp[i-1][2];//当前位可以是0-(num[i]-1),把4的情况单独提出来计算 ,sqr(10,i-1)就是计算当前位上4的个数 else { ans+=(num[i])*dp[i-1][2];//计算当前位是0-3的个数 ans+=k%sqr(10,i-1)+1;//计算当前位是4时,剩下的位置有多少中填法 f=true;//因为如果当前位是4,剩下的位置无论怎么填都是不合法的,打个标记,避免重复计算 } if (num[i+1]==6)//计算含62的情况 { if (num[i]>2) ans+=dp[i][1]; else if (num[i]==2) ans+=k%sqr(10,i-1)+1; } else if (num[i+1]>6) ans+=dp[i][1]; if (num[i+1]==6&&num[i]==2) //因为如果当前位是2,前一位是6,剩下的位置无论怎么填都是不合法的,打个标记,避免重复计算 f=true; } return ans; } int main() { init(); while(scanf("%d%d",&n,&m)) { if (!n&&!m) break; int t=m-n+1-solve(m)+solve(n-1); printf("%d\n",t); } }
相关文章推荐
- HDU-1219 AC Me (水)
- Activity的常用方法和生命周期
- 搜狗输入法人机交互设计的用户体验
- kvm 网桥
- 【HDU 3037】Saving Beans
- FZU-2182 水题
- 从Java future 到 Guava ListenableFuture实现异步调用
- 好日子
- HDU-1229 还是A+B
- urllib.parse.quote
- 电脑硬件参数
- [网站安全] [实战分享]WEB漏洞挖掘的一些经验分享
- Android 简单模仿AsyncHttpClient
- 梦断代码阅读笔记02
- 剑指offer 面试题31:连续子数组的最大和 题解
- HDU-2078 复习时间 (水)
- 个人工作总结06
- 大数据爬虫基础(三)Scrapy在ubuntu 16.04下的安装
- 数据库的简单操作
- jquery dialog