题目
odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1109 Accepted Submission(s): 594
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
题目大意
这里我一定要吐槽一下出题人的英语水平,真的两眼真诚的等着题干老半天,表示直接给绕晕了
题目大体意思是这样来的,让我们找一个叫做奇偶数的东西,什么样的数叫做奇偶数呢,如果这个数里面有连续的奇数,那么连续的奇数的个数一定要是偶数个,比如3333,四个连续的奇数,并且是偶数个,如果这个数里面有连续的偶数,那么连续的偶数的个数一定要是奇数个,比如66666,这里举一个反例122223,里面连续的奇数1,3都是奇数个,连续的偶数2222是偶数个
解题思路
看了半天把题目看懂了,然后发现自己好像看懂了也不会,网上看的题解,然后Get新技能,数位DP
这里是参考的牛人的博客,跟他学的数位DP,看完了再来看我的代码,应该看起来很舒服 传送门 :http://blog.csdn.net/wust_zzwh/article/details/52100392
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
LL L,R;
int case_=1;
LL dp[26][26][26];
LL bit[26];
LL dfs(int pos, int pre ,int len ,int zero, int limit)
{
if(pos<=0) return (pre&1)!=(len&1);
if(!limit&&dp[pos][pre][len]!=-1) return dp[pos][pre][len];
int up=limit?bit[pos]:9;
LL ans=0;
for(int i=0;i<=up;i++)
{
if(zero)
{
if(i==0)
ans+=dfs(pos-1,0,0,1,limit&&i==bit[pos]);
else
ans+=dfs(pos-1,i&1,len+1,0,limit&&i==bit[pos]);
}
else if(i&1)///当前位是奇数
{
if(pre&1)///前一位也是奇数,那么继续向下深入
ans+=dfs(pos-1,i&1,len+1,0,limit&&i==bit[pos]);
else ///前一位是偶数
{
if((pre&1)!=(len&1))
ans+=dfs(pos-1,i&1,1,0,limit&&i==bit[pos]);
}
}
else ///当前位是偶数
{
if(pre&1)
{
if((pre&1)!=(len&1))
ans+=dfs(pos-1,i&1,1,0,limit&&i==bit[pos]);
}
else
ans+=dfs(pos-1,i&1,len+1,0,limit&&i==bit[pos]);
}
}
if(!limit) dp[pos][pre][len]=ans;
return ans;
}
LL solve(LL x)
{
///cout<<"come in\n";
memset(dp,-1,sizeof(dp));
int pos=0;
while(x)
{
bit[++pos]=x%10;
x/=10;
}
///cout<<"solve\n";
return dfs(pos,0,0,1,1);
///cout<<"dfs\n";
}
void work()
{
scanf("%lld%lld",&L,&R);
printf("Case #%d: %lld\n",case_++,solve(R)-solve(L-1));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
work();
}
return 0;
}