不要62
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 30264 Accepted Submission(s): 10657
Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有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
题解:
转自:http://blog.csdn.net/wangyuquanliuli/article/details/13761661
数位dp适合在一段数的区间内找出满足某些条件的数的个数,这个时候往往不能之间遍历,肯定会超时,则一般使用数位dp来解决
数位dp的常见形式是dp[i][j],表示开头是j的i位数满足条件的有多少个,当然也有其他dp[i][j][k]等等,但i,j,k都很小,不会像直接遍历那么耗时
像这道题的话,知道了dp[i][j]表示的是啥,就能列出状态转移方程(稍微认真看就能理解的):
注意:
一开始也想到了数位dp,但是感觉太烦没想做,后来想想,只要从高位往低位累加dp的值就好了
转移方程:
1 for(int i=1;i<=7;i++) 2 { 3 for(int j=0;j<10;j++)//枚举第i位可能出现的数 4 { 5 for(int k=0;k<10;k++)//枚举第i-1位可能出现的数 6 { 7 if(j!=4&&!(j==6&&k==2)) 8 dp[i][j] += dp[i-1][k]; 9 } 10 } 11 }
16562586 | 2016-03-15 17:40:14 | Accepted | 2089 | 0MS | 1564K | 1502 B | G++ | czy |
我的代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <map> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <string> 8 9 using namespace std; 10 11 #define N 1005 12 #define ll long long 13 #define mod 7 14 15 int n,m; 16 int dp[10][10]; //长度为i,以j开头的数目 17 int dir[10]; 18 19 void ini() 20 { 21 memset(dp,0,sizeof(dp)); 22 dp[0][0] = 1; 23 int i,j,k; 24 for(i = 1;i < 10 ;i++){ 25 for(j = 0;j <= 9 ;j++){ 26 if(j == 4) continue; 27 for(k = 0;k <= 9;k++){ 28 if( (k == 4) || (k == 2 && j == 6) ) continue; 29 dp[i][j] += dp[i-1][k]; 30 } 31 } 32 } 33 } 34 35 int solve(int x) 36 { 37 int re = 0; 38 int len = 0; 39 while(x) 40 { 41 dir[++len] = x % 10; 42 x /= 10; 43 } 44 dir[len+1] = 0; 45 int i,j; 46 for(i = len;i >= 0;i--){ 47 for(j = 0;j < dir[i];j++){ 48 if(j == 4) continue; 49 if(j == 2 && dir[i+1]==6) continue; 50 re += dp[i][j]; 51 } 52 if( (dir[i] == 4) || (dir[i] == 2 && dir[i+1] == 6 ) ) break; 53 } 54 return re; 55 } 56 57 int main() 58 { 59 //freopen("in.txt","r",stdin); 60 //freopen("out.txt","w",stdout); 61 ini(); 62 //scanf("%d",&TT); 63 //while(TT--){ 64 while(scanf("%d%d",&n,&m)!=EOF){ 65 if(n == 0 && m == 0) break; 66 //scanf("%d",&n); 67 //printf(" %d ",solve(m+1) ); 68 printf("%d ",solve(m+1) - solve(n)); 69 //cout << mp[ s[ n%294 ] ] << endl; 70 } 71 return 0; 72 }