# odd-even number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 454    Accepted Submission(s): 245

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

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int dig[20];
ll dp[20][20][10];

ll dfs(int pos, int len, int oi, int flag0, int lim) {
if(pos == -1) return ((len % 2 == 0 && oi % 2 != 0) || (len % 2 != 0 && oi % 2 == 0));
if(!lim && dp[pos][len][oi] != -1) return dp[pos][len][oi];
int End = lim ? dig[pos] : 9;
ll ret = 0;
for(int i = 0; i <= End; i++) {
if(i == 0 && flag0) ret += dfs(pos - 1, 0, 0, 1, (i==End) && lim);
else {
int nlen, noi;
noi = i;
if(noi % 2 == oi % 2) nlen = len + 1;
else {
if(!((len % 2 == 0 && oi % 2 != 0) || (len % 2 != 0 && oi % 2 == 0) || len == 0)) {
continue;
}
else nlen = 1;
}
ret += dfs(pos - 1, nlen, noi, 0, (i==End) && lim);
}
}
if(!lim) dp[pos][len][oi] = ret;
return ret;
}

ll func(ll num) {
int n = 0;
while(num) {
dig[n++] = num % 10;
num /= 10;
}
return dfs(n - 1, 0, 0, 1, 1);
}

int main() {
int t;
scanf("%d", &t);
int cas = 0;
memset(dp, -1, sizeof(dp));
while(t--) {
ll l, r;
scanf("%I64d %I64d", &l, &r);
printf("Case #%d: %I64d\n", ++cas, func(r) - func(l-1));
}
}

posted @ 2016-09-20 17:01  MartinEden  阅读(...)  评论(...编辑  收藏