hdu2089不要62


初学数位

#include<stdio.h>
#include<string.h>
int f[6][3],n,m;
//f[i][0]表示前i位吉利的个数
//f[i][1]表示前i位以2为首位的吉利个数
//f[i][2]表示前i位长的数字中不吉利数字的个数,1~999……9(i个9)
void pre()
{
    int i;
    memset(f,0,sizeof(f));
    f[0][0]=1;
    for(i=1;i<=6;i++)
    {
        f[i][0]=9*f[i-1][0]-f[i-1][1];          //前i-1位的吉利个数减去第i位是6第i-1位是2
        f[i][1]=f[i-1][0];                      //前i-1位是吉利的,第i为是2
        f[i][2]=f[i-1][2]*10+f[i-1][1]+f[i-1][0];//前i-1位是非吉利的话,第i位任意,加上第i位是4以及第i为是6第i-1位是2
    }
}
int cal(int n)
{
    int i,l=0,ans=0,b[10],N=n;
    bool flag=false;
    while(n)
    {
        b[++l]=n%10;
        n/=10;
    }
    b[l+1]=0;
    for(i=l;i>0;i--)
    {
        ans+=f[i-1][2]*b[i];                //处理了i-1位里面存在不吉利
        if(flag)
        {
            ans+=f[i-1][0]*b[i];
            continue;
        }
        if(b[i]>4) ans+=f[i-1][0];          //第i位大于4的话,存在第i位去4的非吉利
        if(b[i+1]==6&&b[i]>2) ans+=f[i][1];
        if(b[i]>6) ans+=f[i-1][1];
        if((b[i+1]==6&&b[i]==2)||(b[i]==4)) flag=true;
    }
    return N-ans;
}
int main()
{
    pre();
    while(scanf("%d%d",&n,&m)!=EOF&&n&&m)
    {
        printf("%d\n",cal(m+1)-cal(n));
    }
    return 0;
}


你可能感兴趣的:(hdu2089不要62)