题目链接:https://vjudge.net/contest/365059#problem/K
题目大意:
每个奇数出现的次数是偶数,每个偶数出现的次数是奇数的数的个数
想法:
其实这题可以直接对每个位数都开一个大小为 2 的数组直接水过去。但是这并不是正解
正解是我们同样需要进行状态压缩把这个数转化为三进制数,0 代表未出现,1 代表出现奇数,2 代表出现偶数次
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #include <cstring> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 2e5 + 10; const int mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; LL L,R; int b[25]; int len; LL mem[25][60000]; bool is_ok(int x) { int num[10]; for (int i = 0;i <= 9;i++) { num[i] = x % 3; if (num[i] == 2 && i % 2 == 0) return 0; if (num[i] == 1 && i % 2 == 1) return 0; x /= 3; } return 1; } int update(int x,int n) { int num[10]; for (int i = 0;i <= 9;i++) { num[i] = x % 3; x /= 3; } if (num[n] == 0) num[n] = 1; else num[n] = 3-num[n]; int ans = 0,xx = 1; for (int i = 0;i <= 9;i++) { ans += num[i] * xx; xx *= 3; } return ans; } LL dfs(int cur,int k,bool f,bool g) { if (cur < 0) { if (is_ok(k)) return 1; else return 0; } if (!f && mem[cur][k] != -1) return mem[cur][k]; int v = 9; if (f) v = b[cur]; LL ans = 0; for (int i = 0;i <= v;i++) { if (g) { if (i == 0) ans += dfs(cur-1,0,f&&(i==v),1); else ans += dfs(cur-1,update(k,i),f&&(i==v),0); } else ans += dfs(cur-1,update(k,i),f&&(i==v),0); } if (!f) mem[cur][k] = ans; return ans; } LL solve(LL x) { len = 0; while (x) { b[len++] = x % 10; x /= 10; } return dfs(len-1,0,1,1); } int main() { ios::sync_with_stdio(0); int T; cin >> T; memset(mem,-1, sizeof(mem)); while (T--) { cin >> L >> R; cout << solve(R) - solve(L-1) << endl; } return 0; }