1, HDU 2089  不要62 :http://acm.hdu.edu.cn/showproblem.php?pid=2089

题意:不能出现4,或者相邻的62,

  dp[i][0],表示不存在不吉利数字 

   dp[i][1],表示不存在不吉利数字,且最高位为2 

       dp[i][2],表示存在不吉利数字

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int dp[10][3];

void Init(){    //预处理,算出所有可能
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=8;i++){
        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];   //在不含不吉利数62和4的首位分别补除了4的9个数字,减去在2前面补6的个数
        dp[i][1]=dp[i-1][0];        //在不含不吉利数在首位补2
        dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];   //各种出现不吉利数的情况
    }
}

int Solve(int x){
    int digit[15];
    int cnt=0,tmp=x;
    while(tmp){
        digit[++cnt]=tmp%10;
        tmp/=10;
    }
    digit[cnt+1]=0;
    int flag=0,ans=0;
    for(int i=cnt;i>0;i--){
        ans+=digit[i]*dp[i-1][2];   //由上位所有不吉利数推导
        if(flag)     //之前出现不吉利的数字
            ans+=digit[i]*dp[i-1][0];
        else{
            if(digit[i]>4)   //出现4
                ans+=dp[i-1][0];
            if(digit[i]>6)   //出现6
                ans+=dp[i-1][1];
            if(digit[i+1]==6 && digit[i]>2)  //出现62
                ans+=dp[i][1];
        }
        if(digit[i]==4 || (digit[i+1]==6 && digit[i]==2))
            flag=1;
    }
    return x-ans;   //所有的数减去不吉利的数
}

int main(){

    //freopen("input.txt","r",stdin);

    int a,b;
    Init();
    while(~scanf("%d%d",&a,&b)){
        if(a==0 && b==0)
            break;
        printf("%d\n",Solve(b+1)-Solve(a));
    }
    return 0;
}
View Code

相关文章: