链接:https://ac.nowcoder.com/acm/problem/19945
来源:牛客网
题目描述
输入描述:
输入文件内容只有一行,为空格分隔的2个正整数L,R。
10^10 ≤ L ≤ R < 10^11
输出描述:
输出文件内容只有一行,为1个整数,表示满足条件的手机号数量。
输入
12121284000 12121285550
输出
5
说明
样例解释
满足条件的号码: 12121285000、 12121285111、 12121285222、 12121285333、 12121285550
析:很容易可以看出来是一个数位DP,dp[pos][last][sum][num][enough]表示前 pos 位,上一位是last,已经出现了sum次,num是一个二进制位的表示是否出现过4或者8,enough表示是否已经连续出现过三个相同的数字,然后就很简单了。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <cmath> #include <stack> #include <sstream> #include <list> #include <assert.h> #include <bitset> #include <numeric> #define debug() puts("++++") #define gcd(a, b) __gcd(a, b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a, b, sizeof a) #define sz size() #define be begin() #define ed end() #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define FOR(i,n,x) for(int i = (x); i < (n); ++i) #define freopenr freopen("in.in", "r", stdin) #define freopenw freopen("out.out", "w", stdout) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const LL LNF = 1e17; const double inf = 1e20; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 5e5 + 7; const int maxm = 2000000 + 7; const LL mod = 1e9 + 9; const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1}; const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1}; int n, m; inline bool is_in(int r, int c) { return r >= 0 && r < n && c >= 0 && c < m; } LL dp[15][10][15][4][2]; int a[15]; int is_first; LL dfs(int pos, int last, int sum, int num, bool enough, bool ok){ if(!pos) return num != 3 && enough; LL &ans = dp[pos][last][sum][num][enough]; if(!ok && ans != -1) return ans; int start = is_first; is_first = 0; int n = ok ? a[pos] : 9; LL res = 0; for(int i = start; i <= n; ++i){ if(i == 4 && !(num&2)) res += dfs(pos-1, i, last == i ? sum+1 : 1, num|1, enough || (last==i && sum >= 2), ok && i == n); else if(i == 8 && !(num&1)) res += dfs(pos-1, i, last == i ? sum+1 : 1, num|2, enough || (last==i && sum >= 2), ok && i == n); else if(!i || i % 4) res += dfs(pos-1, i, last == i ? sum+1 : 1, num, enough || (last==i && sum >= 2), ok && i == n); } if(!ok) ans = res; return res; } LL solve(LL n){ if(n < 10000000000LL) return 0LL; int len = 0; while(n){ a[++len] = n % 10; n /= 10; } is_first = 1; return dfs(len, 0, 0, 0, 0, true); } int main(){ ms(dp, -1); LL n, m; cin >> m >> n; cout << solve(n) - solve(m-1) << endl; return 0; }