For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).
Input
First line a t,then t cases.every line contains two integers L and R.
Output
Print the output for each case on one line in the format as shown below.
Sample Input
2
1 100
110 220
Sample Output
Case #1: 29
Case #2: 36
题意:统计 连续的奇数必须是偶数个,连续的偶数必须是奇数个的个数
这里不出现也算奇数个
状态很好想 上一个数 和 连续的长度 奇偶变化 长度就要重新算。
还有一个难点就是前导0的处理,加一个参数 zero 就可以
一开始以为同奇数同偶数才能继续走下去。后来发现不对 22333这样的就gg了。 所以应该是如果偶数的长度不是奇数就不允许转换,只有为奇数才允许转换。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
int wei[30];
ll dp[30][30][30];
ll dfs(int pos,int zero,int len,int pre,int flag)
{
if(pos<0){
return (pre&1)!=(len&1);
}
if(!flag&&dp[pos][pre&1][len]!=-1){
return dp[pos][pre&1][len];
}
int up=flag?wei[pos]:9;
ll res=0;
for(int i=0;i<=up;i++)
{
if(zero)
{
if(i==0)
res+=dfs(pos-1,1,0,0,flag&&i==up);
else
res+=dfs(pos-1,0,1,i,flag&&i==up);
}
else
{
if(pre&1)
{
if(i&1)
res+=dfs(pos-1,0,len+1,i,flag&&i==up);
else if(!(len&1))
res+=dfs(pos-1,0,1,i,flag&&i==up);
}
else
{
if(i&1)
{
if(len&1)
res+=dfs(pos-1,0,1,i,flag&&i==up);
}
else
res+=dfs(pos-1,0,len+1,i,flag&&i==up);
}
}
}
if(!flag)
dp[pos][pre&1][len]=res;
return res;
}
ll change(ll x)
{
ll res=0;
int len=0;
while(x)
{
wei[len++]=x%10;
x/=10;
}
res=dfs(len-1,1,0,0,1);
return res;
}
int main()
{
int t;
cin>>t;
memset(dp,-1,sizeof(dp));
for(int f=1;f<=t;f++)
{
ll a,b;
cin>>a>>b;
printf("Case #%d: %lld\n",f,change(b)-change(a-1));
}
}