洛谷 SP10606 BALNUM - Balanced Numbers

题目描述

Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if:

1) Every even digit appears an odd number of times in its decimal representation

2) Every odd digit appears an even number of times in its decimal representation

For example, 77, 211, 6222 and 112334445555677 are balanced numbers while 351, 21, and 662 are not.

Given an interval [A, B], your task is to find the amount of balanced numbers in [A, B] where both A and B are included.

输入格式

The first line contains an integer T representing the number of test cases.

A test case consists of two numbers A and B separated by a single space representing the interval. You may assume that 1 <= A <= B <= 10 ^{19}19

输出格式

For each test case, you need to write a number in a single line: the amount of balanced numbers in the corresponding interval

题意翻译

一个数被称为是平衡的数,当且仅当对于所有出现过的数位(即 0-909 ),每个偶数出现奇数次,每个奇数出现偶数次。给定 A,BA,B,请统计出 [A,B][A,B] 内所有平衡数的个数。

1\leq A\leq B\leq 10^{19}1AB1019

输入输出样例

输入 #1
2
1 1000
1 9
输出 #1
147
4

原网址:https://www.luogu.com.cn/problem/SP10606

思路:打开一看我们就能感受到是数位dp,然而再观察一下之后我们发现还需要对每个数字记录是否出现过以及出现过的奇偶性,所以我们还需要一个状态来记录这些,然后因为0-9只有10个数,所以很好想到这题要状压。
可惜的是这里每个数有3种状态,而作为一个蒟蒻表示这也太难写了,所以最后不厌其烦搞了一个12维数组来做。(写得太烦了看了眼评论区的式子。
需要注意的是这里要把前导零特殊处理掉。

下面附上ac代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define ll long long
 5 using namespace std;
 6 int cnt[25];
 7 ll dp[25][3][3][3][3][3][3][3][3][3][3][3],l,r;
 8 ll dfs(int x,int lz,int jb,int c0,int c1,int c2,int c3,int c4,int c5,int c6,int c7,int c8,int c9){
 9     if (!x){
10         return c0 && c1^1 && c2 && c3^1 && c4 && c5^1 && c6 && c7^1 && c8 && c9^1;
11     }
12     if(!jb&&dp[x][lz][c0][c1][c2][c3][c4][c5][c6][c7][c8][c9]!=-1) return dp[x][lz][c0][c1][c2][c3][c4][c5][c6][c7][c8][c9];
13     int maxx;
14     ll ret=0;
15     if (jb) maxx=cnt[x];
16     else maxx=9;
17     for (int i=0; i<=maxx; i++){
18         ret+=dfs(x-1,lz &&!i, jb && i==maxx,!i && !lz?(c0+1)&1:c0,i==1?(c1+1)&1:c1,i==2?(c2+1)&1:c2,i==3?(c3+1)&1:c3,i==4?(c4+1)&1:c4,i==5?(c5+1)&1:c5,i==6?(c6+1)&1:c6,i==7?(c7+1)&1:c7,i==8?(c8+1)&1:c8,i==9?(c9+1)&1:c9);
19     }
20     if (!jb) dp[x][lz][c0][c1][c2][c3][c4][c5][c6][c7][c8][c9]=ret;
21     return ret;
22 }
23 int main(){
24     int T;
25     scanf("%d",&T);
26     memset(dp,-1,sizeof(dp));
27     while (T--){
28         scanf("%lld%lld",&l,&r);
29         l--;
30         int len=0;
31         while (l){
32             cnt[++len]=l%10;
33             l/=10;
34         }
35         ll res1=dfs(len,1,1,2,2,2,2,2,2,2,2,2,2);
36         len=0;
37         while (r){
38             cnt[++len]=r%10;
39             r/=10;
40         }
41         ll res2=dfs(len,1,1,2,2,2,2,2,2,2,2,2,2);
42         printf("%lld\n",res2-res1);
43     }
44     return 0;
45 }
View Code

 

posted @ 2020-10-01 21:13  我是菜狗QAQ  阅读(198)  评论(0编辑  收藏  举报