Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 25866 Accepted Submission(s): 9810
#include<iostream> #include<string.h> #define ll long long using namespace std; ll shu[20], dp[20][2]; ll dfs(ll len, bool if4, bool shangxian) { if (len == 0) return 1; if (!shangxian&&dp[len][if4]) return dp[len][if4]; ll mx, cnt = 0;//cnt记录的是区间内不含49的个数 mx = (shangxian ? shu[len] : 9); for (ll i = 0; i <= mx; i++) { if (if4&&i == 9)//如果shu[len]==4&&上一个状态是9 continue; cnt = cnt + dfs(len - 1, i == 4, shangxian&&i == mx); } return shangxian ? cnt : dp[len][if4] = cnt; } ll solve(ll n) { memset(shu, 0,sizeof(shu)); ll k = 0; while (n)//将n的每一位拆解出来逆序存在shu[i]中。eg:109,shu[0]=9,shu[1]=0,shu[2]=1; { shu[++k] = n % 10;//注意这里是++k n = n / 10; } return dfs(k, false, true); } int main() { ll t; scanf("%lld", &t); while (t--) { ll n; scanf("%lld", &n);//这里计算的区间是[0,n],题目要计算的是[1,n]; printf("%lld\n", n-(solve(n)-1)); //如果是计算区间[a,b];printf(solve(b)-solve(a-1)); } return 0; }
原文:https://www.cnblogs.com/-citywall123/p/10745755.html