hdu-2089-数位dp
不要62
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 53603 Accepted Submission(s): 20513
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
f[i][j]表示以j开头的i位数合法数的数量,可以先预处理出来这个数组,f[i][j]=SUM{ f[i-1][k] | (j!=4)&&(当j==6时k!=2) }。
之后利用这个数组解决[1,n]的数目这个问题,对于一个数从高位到低位统计,假设345就可以分成[000,099]=f[3][0],[100,199]=f[3][1],[200,299]=f[3][2],[300,339]=f[2][0]+f[2][1]+f[2][2]+f[2][3],[340,345]=f[1][0]+f[1][1]+f[1][2]+f[1][3]+f[1][4]+f[1][5],注意有时候分到一些区间整个区间都不合法直接退出就好了,例如上面的[340,345],都有4所以不必再统计下去,或者都有62作为前缀。还有就是cal()函数统计的范围是[1,n)(因为除了最低位其他位都枚举到bit[i]-1就停止,为了方便编写直接让n+1也可 )记得先+1再计算。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int f[10][10]; 4 int bit[10]; 5 int cal(int N){ 6 int ans=0,len=0; 7 while(N){ 8 bit[len++]=N%10; 9 N/=10; 10 } 11 bit[len]=0; 12 for(int i=len-1;i>=0;--i){ 13 for(int j=0;j<bit[i];++j) 14 { 15 if(j==2&&bit[i+1]==6) continue; 16 ans+=f[i+1][j]; 17 } 18 if(bit[i]==4||(bit[i]==2&&bit[i+1]==6)) 19 break; 20 } 21 return ans; 22 } 23 int main(){ 24 int i,j,k; 25 f[0][0]=1; 26 for(i=1;i<=7;++i){ 27 for(j=0;j<=9;++j){ 28 if(j==4) continue; 29 for(k=0;k<=9;++k){ 30 if(k==4 || (j==6&&k==2) ) continue; 31 f[i][j]+=f[i-1][k]; 32 } 33 } 34 } 35 int l,r; 36 while(cin>>l>>r&&(l||r)){ 37 printf("%d\n",cal(r+1)-cal(l+1-1)); 38 } 39 40 return 0; 41 }