Problem Description
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
Source
2016 ACM/ICPC Asia Regional Shenyang Online
分析:每位一共五个状态(有前导零,奇数个奇数,偶数个奇数,奇数个偶数,偶数个偶数),然后特殊处理下全是0的情况就可以了。
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
#include<unordered_map>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define MOD 1000000007
#define MAXN 100005
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int T,a[20];
ll dp[20][5];
ll dfs(int pos,bool lead,bool limit,int sta)
{
if(pos == -1) return (sta == 1 || sta == 3) && !lead;
if(!limit && !lead && dp[pos][sta] >= 0) return dp[pos][sta];
int up = limit ? a[pos] : 9;
ll ans = 0;
for(int i = 0;i <= up;i++)
{
if(lead) ans += dfs(pos-1,lead && !i,limit && (i == up),(i & 1) ? 2 : 1);
else
{
if((sta == 0) && (i & 1)) continue;
if((sta == 2) && !(i & 1)) continue;
if(sta == 3) ans += dfs(pos-1,0,limit && (i == up),(i & 1) ? 2 : 1);
if(sta == 2) ans += dfs(pos-1,0,limit && (i == up),3);
if(sta == 1) ans += dfs(pos-1,0,limit && (i == up),(i & 1) ? 2 : 0);
if(sta == 0) ans += dfs(pos-1,0,limit && (i == up),1);
}
}
if(!limit && !lead) dp[pos][sta] = ans;
return ans;
}
ll solve(ll x)
{
int pos = 0;
while(x)
{
a[pos++] = x % 10;
x /= 10;
}
memset(dp,-1,sizeof(dp));
return dfs(pos-1,1,1,4);
}
int main()
{
scanf("%d",&T);
for(int t = 1;t <= T;t++)
{
ll l,r;
scanf("%lld%lld",&l,&r);
printf("Case #%d: %lld\n",t,solve(r) - solve(l-1));
}
}