[HDU 2089]不要62

题目描述

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。

杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有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; 
} 
原文地址:https://www.cnblogs.com/lher/p/6670713.html