题目描述
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
输入
输入的都是整数对n、m(0<=n<=m<2147483647),如果遇到都是0的整数对,则输入结束。
输出
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
样例输入
1 100
0 0
样例输出
80
dp[i][j]表示开头是j的i位数中不含“62”或“4”的数有几个
统计答案时,我们查询[0,m]-[0,n)即可
如何查询[0,i)呢?设i=693(举个例子)
那么统计答案时,加上f[0~5][3],这样就把0~599的数都给统计完了
然后如果高位没有出现4或62,由于0~89的不含有不吉利数字与600~689的不含有不吉利数字的个数相同(高位没有出现4或62),所以我们再加上f[0~8][2],这样就统计完了0~689的数
如果高位没有出现4或62,再加上f[0~2][1],就好了
#include<cstdio> int dp[11][11]; void init() { dp[0][0]=1; for(int i=1;i<=8;i++) for(int j=0;j<=9;j++) //j表示第i位数是j for(int k=0;k<=9;k++) //k表示第i-1位数是k if(j!=4&&!(j==6&&k==2))dp[i][j]+=dp[i-1][k]; } int solve(int i) { int d[10],j=1,ans=0; while(i!=0) { d[j++]=i%10;i/=10; } d[j]=0; for(--j;j>=1;j--) { for(int k=0;k<d[j];k++) //注意,不能取等,所以solve求得是[0,n) { if(k!=4&&!(d[j+1]==6&&k==2)) //前面不能出现62或4 ans+=dp[j][k]; } if(d[j]==4||(d[j]==2&&d[j+1]==6)) break; } return ans; } int main() { init();int n,m; scanf("%d%d",&n,&m); while(1) { if(n==0&&m==0)break; printf("%d ",solve(m+1)-solve(n)); scanf("%d%d",&n,&m); } return 0; }