题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个。
题解:这是数位DP的入门题了,首先要理解数DP的原理,DP[i][j]:代表第i位的第j值,举个栗子:如4715 数位数是从右向左的,则第一位是5,第二位是1,第三位是7,第四位是4。所以如果要求0到4715,ans=dp[4][x]+dp[3][y]+dp[2][z]+dp[1][k]
0<=x<=4(但是4要去掉),0<=y<=9,0<=z<=9,0<=k<=9(还要注意判断,把其中62,和4去掉)
AC代码:
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; typedef long long ll; typedef unsigned long long ull; #define prN printf(" ") #define SI(N) scanf("%d",&(N)) #define SII(N,M) scanf("%d%d",&(N),&(M)) #define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K)) #define cle(a,val) memset(a,(val),sizeof(a)) #define rep(i,b) for(int i=0;i<(b);i++) #define Rep(i,a,b) for(int i=(a);i<=(b);i++) #define reRep(i,a,b) for(int i=(a);i>=(b);i--) const int MAX_N= 1000+5 ; const double eps= 1e-9 ; int dp[10][10]; int sol(int n) { int *dig=new int [10]; int len=1; while(n) { dig[len++]=n%10; n/=10; } int ans=0; for (int i=len-1; i!=0; i--) { for (int j=0; j<dig[i]; j++) { if (j!=4&&!(dig[i+1]==6&&j==2)) ans+=dp[i][j]; } if (dig[i]==4||(dig[i]==2&&dig[i+1]==6)) break; } return ans; } int main() { #ifndef ONLINE_JUDGE // freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin); // freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout); #endif // ONLINE_JUDGE dp[0][0]=1; for (int i=1; i<=7; i++) { for (int j=0; j<=9; j++) { for (int k=0; k<=9; k++) { if (j!=4&&(j!=6||k!=2)) { dp[i][j]+=dp[i-1][k]; } } } } int l,r; while(cin>>l>>r,l||r) { cout<<sol(r+1)-sol(l)<<endl; } return 0; }