odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 594 Accepted Submission(s): 327
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
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int a[20];
//oddnum要为0,evennum要为1
LL f[64][2][3];
//oddnum和evennum为之前传过来的段数
LL dp(int p, bool tp, int len, int last)
{
if (p == -1)return len ^ last;
if (!tp && ~f[p][len][last])return f[p][len][last];
LL ret = 0;
int top = tp ? a[p] : 9;
for (int i = 0; i <= top; ++i)
{
if (i == 0 && last == 2)
{
ret += dp(p - 1, tp&i == top, 0, 2);
continue;
}
int x = i & 1;
if (x == last)ret += dp(p - 1, tp&i == top, len ^ 1, x);
else if (len ^ last)ret += dp(p - 1, tp&i == top, 1, x);
}
if (!tp)f[p][len][last] = ret;
return ret;
}
LL DP(LL x)
{
int p = -1; while (x)a[++p] = x % 10, x /= 10;
if (p == -1)a[++p] = 0;
MS(f, -1);
return dp(p, 1, 0, 2);
}
int main()
{
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
LL l, r;
scanf("%lld%lld", &l, &r);
LL ans = DP(r) - DP(l - 1);
printf("Case #%d: %lld\n", casei, ans);
}
return 0;
}
/*
【题意】
求区间范围内有多少个数,使得该数连续的偶数段的长度都为奇数,连续的奇数段的长度都为偶数
【类型】
数位DP
【分析】
这道题是数位DP
数位DP常常是把高位的状态向低位传。
同时常常要考虑前导零
*/