题意:给出一个区间[l, r],问其中数位中连续的奇数长度为偶数并且连续的偶数长度为奇数的个数。(1<=L<=R<= 9*10^18)
例如 12223333 就不满足条件,因为存在奇数个奇数(1个1)
#include<bits/stdc++.h>
#define LL long long
#define N 100010
#define INF 0x3f3f3f3f
using namespace std;
LL dp[25][25][25];
int bit[25];
/// 第几位 前一个状态 连续长度 是否存在前缀0, flag边界问题
LL dfs(int pos,int pre,int len,bool zero,bool flag){
if(pos<=0) return (pre&1)!=(len&1);
if(flag&&dp[pos][pre][len]!=-1) return dp[pos][pre][len];
int d=flag?9:bit[pos];
LL ans=0;
for(int i=0;i<=d;i++){
if(zero){
if(i==0) ans+=dfs(pos-1,0,0,1,flag||i!=d);
else ans+=dfs(pos-1,i&1,1,0,flag||i!=d);
}
else {
if(i&1){
if(pre&1) ans+=dfs(pos-1,i&1,len+1,0,flag||i!=d);
else{
if(len&1) ans+=dfs(pos-1,i&1,1,0,flag||i!=d);
}
}
else{
if(pre&1){
if(!(len&1)) ans+=dfs(pos-1,i&1,1,0,flag||i!=d);
}
else ans+=dfs(pos-1,i&1,len+1,0,flag||i!=d);
}
}
}
if(flag) dp[pos][pre][len]=ans;
return ans;
}
LL solve(long long x)
{
int len = 0;
while(x) {
bit[++len] = x % 10;
x /= 10;
}
return dfs(len, 0, 0, 1, 0); ///zero应该初始化为 1,表示存在前导零
}
int main()
{
int t;
scanf("%d", &t);
for(int cas = 1; cas <= t; cas++) {
memset(dp, -1, sizeof(dp));
long long l, r;
scanf("%I64d%I64d", &l, &r);
printf("Case #%d: %I64d\n", cas, solve(r) - solve(l - 1));
}
return 0;
}