1 int pos=0; 2 while(k) 3 { 4 num[++pos]=k%10; 5 k/=10; 6 }
1 inline int dfs(int pos,int pre,int sta,bool limit)//pos:位数,pre:前驱,sta前一位是否是6,若不是则可以记忆化,否则因 2 //这一位2不能取而不能记忆化 limit:判断当前位的枚举上限 3 { 4 if(pos==0) return 1;//表示找到了最低位仍合法证明找到了一个数 5 if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];//记忆化不是上限的0-9过程 6 int up,sum=0; 7 if(!limit) up=9; else up=num[pos];//判断这位的枚举上限 8 for(int i=0;i<=up;i++)//枚举这一位的所有可能 9 { 10 if(i==4) continue;//去掉4的情况 11 if(pre==6&&i==2) continue;//去掉前驱是6,这位是2的情况 12 sum+=dfs(pos-1,i,i==6,limit&&(i==num[pos]));//搜 13 } 14 if(!limit) dp[pos][sta]=sum; 15 return sum; 16 }
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; int dp[20][2],num[20]; inline int dfs(int pos,int pre,int sta,bool limit) { if(pos==0) return 1; if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta]; int up,sum=0; if(!limit) up=9; else up=num[pos]; for(int i=0;i<=up;i++) { if(i==4) continue; if(pre==6&&i==2) continue; sum+=dfs(pos-1,i,i==6,limit&&(i==num[pos])); } if(!limit) dp[pos][sta]=sum; return sum; } inline int solve(int k) { int pos=0; while(k) { num[++pos]=k%10; k/=10; } return dfs(pos,0,0,true); } int main() { int m,n; memset(dp,-1,sizeof(dp)); while(1) { scanf("%d%d",&m,&n); if(m==0&&n==0) return 0; printf("%d\n",solve(n)-solve(m-1)); } return 0; }
来源:博客园
作者:Hoyoak
链接:https://www.cnblogs.com/Hoyoak/p/11432776.html