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
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll dp[20][2][2];//dp[len][pre][e] 代表第几位,之前一位是奇数还是偶数,e表示是否还要添加一个与pre同为奇数或者偶数的数。
int a[20];
ll dfs(int len,int pre,int e,bool flag,bool s)//pre 表示上一个数,0表示偶数,1表示奇数。e=0不需要添加。e=1需要添加。s记录前缀和,s=false前面全是0,
{
if(len<0)
{
return e==1?0:1;
}
if(flag==false&&dp[len][pre][e]!=-1&&s)
{
return dp[len][pre][e];
}
ll ans=0;
int cnt=flag?a[len]:9;
for(int i=0;i<=cnt;i++)
{
if(s==false)
{
if(i==0)
{
ans+=dfs(len-1,0,0,flag&&i==cnt,false);
}
else
{
ans+=dfs(len-1,i%2,i%2==1?1:0,flag&&i==cnt,true);
}
}
else if(i%2==1)
{
if(pre%2==1)
{
ans+=dfs(len-1,1,e^1,flag&&i==cnt,true);
}
else
{
if(e==0)
{
ans+= dfs(len-1,1,1,flag&&i==cnt,true);
}
}
}
else
{
if(pre%2==0)
ans+=dfs(len-1,0,e^1,flag&&i==cnt,true);
else
{
if(e==0)
{
ans+=dfs(len-1,0,0,flag&&i==cnt,true);
}
}
}
}
if(!flag&&s)
dp[len][pre][e]=ans;
return ans;
}
ll solve(ll x)
{
int len=0;
memset(a,0,sizeof(0));
while(x>0)
{
a[len++]=x%10;
x/=10;
}
return dfs(len-1,0,0,true,false);
}
int main()
{
int t,ca=1;
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
while(t--)
{
long long int l,r;
scanf("%I64d%I64d",&l,&r);
printf("Case #%d: %I64d\n",ca++,solve(r)-solve(l-1));
}
return 0;
}