题意:给出一个区间[l, r],问其中数位中连续的奇数长度为偶数并且连续的偶数长度为奇数的个数。(1<=L<=R<= 9*10^18)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[25][25][2];
//第一维表示长度、第二维表示连续长度、第三维是否存在前缀0
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][len][pre] != -1)
return dp[pos][len][pre];
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, true, flag || i != d);
else
ans += dfs(pos-1, i&1, 1, false, flag || i != d);
}
else
{
if(i&1)
{
if(pre & 1)
ans += dfs(pos-1, i&1, len+1, false, flag || i != d);
else if(len & 1) ans += dfs(pos-1, i&1, 1, false, flag || i != d);
}
else
{
if(!(pre&1))
ans += dfs(pos-1, i&1, len+1, false, flag || i != d);
else if(!(len&1))
ans += dfs(pos-1, i&1, 1, false, flag || i != d);
}
}
}
if(flag)
dp[pos][len][pre] = ans;
return ans;
}
ll solve(ll x)
{
int len = 0;
while(x)
{
bit[++len] = x % 10;
x /= 10;
}
return dfs(len, 0, 0, true, false);//zero应该初始化为 1,表示存在前导零
}
int main()
{
int T;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++)
{
memset(dp, -1, sizeof(dp));
ll l, r;
scanf("%I64d%I64d", &l, &r);
printf("Case #%d: %I64d\n", kase, solve(r) - solve(l-1));
}
return 0;
}