HDU2089 一段区间内数字没有62和4的个数
2017-05-11 20:22
351 查看
C - 不要62
HDU- 2089
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
Input输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
Output对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
Sample Input
1 100 0 0
Sample Output
80
自己写的第一道数位dp
dp[i][j] i表示剩余要处理的位数(比如5位数45623 i一开始是5 到0就是都处理完了就回溯 也可以开始是4到-1回溯 ) j(0,1,2)0代表吉利 1代表上一位是6 2表示不吉利 j是表示上一层传下来的状态
dfs(int dex,int dt,int p) dex剩余要处理的位数 dt(012)状态 p(01)是否取到了最高位 (抄cjs的
)
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <climits>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int dp[11][8];
int digits[11];
int dfs(int dex,int dt,int p){ //计算不吉利的数字个数
int ans=0;
if(dex==0) return dt==2;
if(dp[dex][dt]!=-1&&!p) return dp[dex][dt];
int u=p?digits[dex]:9;
for(int i=0;i<=u;i++){
if(i==4||dt==1&&i==2||dt==2) ans+=dfs(dex-1,2,p&&i==u);
else if(i==6) ans+=dfs(dex-1,1,p&&i==u);
else ans+=dfs(dex-1,0,p&&i==u);
}
if(!p) dp[dex][dt]=ans;
return ans;
}
int digit(int num){
int k=0;
while(num){
digits[++k]=num%10;
num/=10;
}
return dfs(k,0,1);
}
int main(){
memset(dp,-1,sizeof(dp));
while(scanf("%d%d",&n,&m)==2&&(n||m)){
int k1=digit(m),k2=digit(n-1);
printf("%d\n",m-n+1-(k1-k2));
}
return 0;
} 或者直接求吉利数字的个数(网上看到不知道是哪位大佬写的)
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,dp[20][2],digit[20];
int dfs(int len,int six,int top)//len剩余处理的位数 上一个数字是否为6 top是否取到最高位
{
if (!len) return 1;
if (!top&&dp[len][six]!=-1) return dp[len][six];
int ans=0,u=top?digit[len]:9;
for (int i=0;i<=u;++i){
if (i==4||six&&i==2) continue;//跳过4和62
ans+=dfs(len-1,i==6,top&&i==u);
}
if (!top)
dp[len][six]=ans;
return ans;
}
int slove(int n)
{
int len=0;
while (n){
digit[++len]=n%10;
n/=10;
}
return dfs(len,0,1);
}
int main()
{
memset(dp,-1,sizeof(dp));
while (scanf("%d%d",&n,&m)>0&&(n||m)){
printf("%d\n",slove(m)-slove(n-1));
}
}
相关文章推荐
- hdu 3911 Black And White 一串0 1的数字 操作将一段区间[ i , j ]的每个数字进行异或操作 问区间最长0|1串
- C#在一段数字区间内随机生成若干个互不相同的随机数
- C#在一段数字区间内随机生成若干个互不相同的随机数
- 【解题报告】HDU 4638 Group - 树状数组 + 求一段区间连续数字的段数
- HDU2089[不要62]
- HDU2089:不要62(数位DP)
- 【hdu2089】不要62 数位dp
- 互联网下半场拉开帷幕,未来没有互联网企业只有数字企业
- 补码中有正负零吗?当然没有!每个数字都是唯一表示的啦
- hdu2089 不要62
- HDU2089 不要62 数位dp
- HDU2089_不要62_数位DP
- 不要62 hdu2089
- 依序遍历0到100闭区间内所有的正整数,如果该数字能被3整除,则输出该数字及‘*’标记;如果该数字能被5整除,则输出该数字及‘#’标记;如果该数字既能被3整除又能被5整除,则输出该数字及‘*#’标记
- 合并多段数字区间的解决方案
- 笔记本电脑(没有num按键)如何关闭数字小键盘
- hdu2089 不要62(数位dp模板)
- 【数字题3】最大重叠子区间
- 题目“求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字”——杭电代码没有满分
- poj 3419 求一段区间内的最长不重复子串