数位DP HDU2089

不要62

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 34469    Accepted Submission(s): 12459


Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为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
 

 

Author
qianneng
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  2094 2090 2091 2093 2092
 
代码:
 1 /*
 2 把每一位数拆开,从高位开始,在这个位置上从0到此数枚举
 3 */
 4 #include<iostream>
 5 #include<string>
 6 #include<cstdio>
 7 #include<cmath>
 8 #include<cstring>
 9 #include<algorithm>
10 #include<vector>
11 #include<iomanip>
12 #include<queue>
13 #include<stack>
14 using namespace std;
15 int n,m,a,b;
16 int dp[7][10];  //i位置上是j
17 void init()      //找出7位数以内所有符合的数
18 {
19     for(int i=1;i<7;i++)
20     {
21         for(int j=0;j<10;j++)
22         {
23             if(j==4) continue;
24             for(int k=0;k<10;k++)
25             {
26                 if(k==4) continue;
27                 if(j==6&&k==2) continue;
28                 dp[i][j]+=dp[i-1][k];
29             }
30         }
31     }
32 }
33 int insum(int x)
34 {
35     int c[10]={0},cnt=1,sum=0;
36     while(x)         //把数拆开存入数组
37     {
38         c[cnt++]=x%10;
39         x/=10;
40     }
41     for(int i=cnt-1;i>0;i--)
42     {
43         for(int j=0;j<c[i];j++)  //枚举第i位取值 
44         {
45             if(j==4) continue;
46             if(j==2&&c[i+1]==6) continue;
47             sum+=dp[i][j];
48         }
49         if(c[i]==4||(c[i]==2&&c[i+1]==6))  //第i位已经不满足条件,则i位以后都不可能满足条件,结束循环  
50         break;
51     }
52     return sum;
53 }
54 int main()
55 {
56     while(scanf("%d%d",&n,&m))
57     {
58         if(n==0&&m==0) break;
59         memset(dp,0,sizeof(dp));
60         dp[0][0]=1;   //初始化
61         init();
62         a=insum(n);              //用[0,m]-[0,n)即可得到区间[n,m]
63         b=insum(m+1);
64         printf("%d\n",b-a);
65     }
66     return 0;
67 }

 

posted @ 2016-08-08 20:02  luckilzy  阅读(211)  评论(0编辑  收藏  举报