题意:
求出所给范围内满足其数位上的奇数出现偶数次,数位上的偶数出现奇数次(或不出现)的数的个数。
思路:
对于0 ~ 9 每个数有3种情况。
1.没出现过 2.出现奇数次 3.出现偶数次
那么就可以用三进制来表示状态。
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; const int N = 60000; int t; int bits[25]; ll l, r; ll dp[25][N]; ll judge(ll x) { for(int i = 0; i <= 9; i++, x/=3) if(x%3 == (i+1)%2+1) return 0; return 1; } ll change(ll x, int pos) { int j = pos; ll res = x; while(j--) res /= 3; res = res%3; if(res < 2) x += (int)pow(3, pos); else x -= (int)pow(3, pos); return x; } ll dfs(int pos, int state, bool limit) { if(pos < 0) return judge(state); if((!limit) && (~dp[pos][state])) return dp[pos][state]; int up = limit?bits[pos]:9; ll res = 0; for(int i = 0; i <= up; i++) res += dfs(pos-1, state==0&&i==0?0:change(state, i), limit && i==up); if(!limit) dp[pos][state] = res; return res; } ll solve(ll x) { int pos = 0; while(x) { bits[pos++] = x%10; x /= 10; } return dfs(pos-1, 0, 1); } int main() { memset(dp, -1, sizeof(dp)); scanf("%d", &t); while(t--) { scanf("%lld%lld", &l, &r); printf("%lld\n", solve(r) - solve(l-1)); } }