AFei loves numbers. He defines the natural number containing “520” as the AFei number, such as 1234520, 8752012 and 5201314. Now he wants to know how many AFei numbers are not greater than n.
輸入描述:
The first line contains an integer T (1 <= T <= 100 ).
The following T lines contain an interger n ( 0 <= n <= 1e18 ).
輸出描述:
For the last T lines, output the total numbers of AFei numbers that are not greater than n.
輸入
2 1000 5520
輸出
1 16
說明
For the first case, only 520 is AFei number.
For the second case, 520,1520, 2520, 3520, 4520, 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209 and 5520 are AFei number. So there are 16 AFei numbers.
思路
計(jì)算不包括520的數(shù)字
dp[ i ][ j ] 表示以數(shù)字 j 結(jié)尾后面剩余 i 位數(shù)字中不包括520的數(shù)字的數(shù)量
dp[ i ][ j ] = ∑k=0k=top\sum_{k=0}^{k=top}∑k=0k=top?dp[ i - 1 ][ (j % 10) * 10 + k ]
計(jì)算包括520的數(shù)字
dp[ i ][ j ][ flag ] 表示以數(shù)字 j 結(jié)尾后面剩余 i 位數(shù)字中包括520的數(shù)字的數(shù)量,其中flag表示走到當(dāng)前位置是否出現(xiàn)過520
// 計(jì)算不包括#include<bits/stdc++.h>#define LL long long#define P pair<int, int>#define lowbit(x) (x & -x)#define mem(a, b) memset(a, b, sizeof(a))#define REP(i, n) for (int i = 1; i <= (n); ++i)#define rep(i, n) for (int i = 0; i < (n); ++i)#define maxn 100005usingnamespace std;int num[20];
LL dp[20][100];
LL dfs(int len,int pre,int limit){if(!len)return1;// 使用dp數(shù)組,前提limit = 0if(!limit && dp[len][pre]!=-1)return dp[len][pre];LL sum =0;int top =9;if(limit) top = num[len];for(int i =0; i <= top;++i){if(i ==0&& pre ==52)continue;sum +=dfs(len-1,(pre%10)*10+ i, limit&&i==top);}// 只有在limit = 0 時(shí),更新dpif(!limit) dp[len][pre]= sum;return sum;}LL solve(LL n){int len =0;LL t = n;while(t){num[++len]= t %10;t /=10;}LL ans =dfs(len,0,1);ans = n +1- ans;printf("%lld\n", ans);return0;}intmain(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);// freopen("out.txt", "w", stdout);#endifmem(dp,-1);int T;scanf("%d",&T);while(T--){LL n;scanf("%lld",&n);solve(n);}return0;}// 計(jì)算包括#include<bits/stdc++.h>#define LL long long#define P pair<int, int>#define lowbit(x) (x & -x)#define mem(a, b) memset(a, b, sizeof(a))#define REP(i, n) for (int i = 1; i <= (n); ++i)#define rep(i, n) for (int i = 0; i < (n); ++i)#define maxn 100005usingnamespace std;int num[20];
LL dp[20][100][2];
LL dfs(int len,int pre,int limit,int flag){if(!len)return flag ?1:0;if(!limit && dp[len][pre][flag]!=-1)return dp[len][pre][flag];int top = limit ? num[len]:9;LL sum =0;for(int i =0; i <= top;++i){if(i ==0&& pre ==52) sum +=dfs(len-1,(pre%10)*10+i, limit&&i==top,1);else sum +=dfs(len-1,(pre%10)*10+i, limit&&i==top, flag);}if(!limit) dp[len][pre][flag]= sum;return sum;}LL solve(LL n){int len =0;LL t = n;while(t){num[++len]= t %10;t /=10;}LL ans =dfs(len,0,1,0);printf("%lld\n", ans);return0;}intmain(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);// freopen("out.txt", "w", stdout);#endifmem(dp,-1);int T;scanf("%d",&T);while(T--){LL n;scanf("%lld",&n);solve(n);}return0;}