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; }