Problem Description
让你求闭合区间内,平衡数的个数。
平衡数:数字由0-9组成,如果是偶数得有奇数个,如果是奇数得有偶数个。
例:12313:1, 3有偶数个,2有奇数个。所以它是要给平衡数
思路:
统计0-9对应的数字是偶还是奇,0是偶,奇是1,可以状态压缩。
还需要处理一个点,就是数字有没有出现过。一开始默认是0,所以偶也默认是0,如果没有出现过就是满足,如果出现过就是不满足。所以我们还需要状态压缩记录 数字是否出现过。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[25][1200][1200];
int a[25];
bool judge(int now, int ex)
{
//printf("%d %d\n", now, ex);
for(int i = 0; i < 10; i++)
{
// printf("ei %d %d\n", ex, i);
if( !((1<<i) & ex) ) continue;
// printf("ni %d %d\n", now, i);
if(i%2 == 0) {
if(!((1<<i) & now)) return 0;
}
else {
if((1<<i) & now) return 0;
}
}
return 1;
}
ll dfs(int pos, int now, int ex, int sta, int limit)//到了第几位,当前状态,是否存在的状态,是否出现过除了0以外的数字,限制
{
if(pos < 0) {
if(judge(now, ex)) return 1;//判断是否满足
else return 0;
}
if(!limit && dp[pos][now][ex] != -1) return dp[pos][now][ex];
int up = limit ? a[pos] : 9;
ll res = 0;
for(int i = 0; i <= up; i++)
{
int ex1 = ex|(1<<i), now1 = now^(1<<i);//更新存在的数字,和当前状态
//printf("res = %lld\n", res);
res += dfs(pos-1, (sta || i != 0) ? now1 : 0, (sta || i != 0) ? ex1 : 0, sta || i != 0, limit && i == a[pos]);
//printf("res = %lld\n", res);
}
if(!limit) return dp[pos][now][ex] = res;
return res;
}
ll solve(ll x)
{
int pos = 0;
while(x)
{
a[pos++] = x%10;
x /= 10;
}
return dfs(pos-1, 0, 0, 0, 1);
}
int main()
{
int T;
cin >> T;
ll lt, rt;
memset(dp, -1, sizeof(dp));
while(T--)
{
cin >> lt >> rt;
cout << solve(rt) - solve(lt-1) << endl;
}
return 0;
}