odd-even number

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<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll L,R,dp[20][2][2];
//dp[pos][pre][num] 
//pos是第几位 
//pre是第pos+1位的数的奇(1)偶(0)性
//num是 第pos位之前保持上一位数的奇偶性的长度的奇偶性
int wei[20];//用来存储数的每一位 
ll work (ll x);
//pos第几位 limit是有没有限制表示第pos位可不可以从0取到9 lead有没有前导零 pre是pos+1位数的奇偶性 
ll dfs(int pos,int limit,int lead,int pre ,int num);
int main()
{
	int t,x;
	cin>>t;
	memset(dp,-1,sizeof(dp));//初始化 
	for(int i=1;i<=t;i++){
		cin>>L>>R;
		printf("Case #%d: %lld\n",i,work(R)-work(L-1));
	}
	return 0;
}
ll work (ll x)
{
	int pos = 0;
	while(x){
		wei[pos++] = x%10;
		x /= 10;
	}//分解x的每一位 倒序 
	return dfs(pos-1,1,1,1,0);//一开始是有限制的 有前导零的 当前前面是一个数都没有长度为0 按照奇偶性num=0 
	//因为前面什么数字都没有 我们要让一开始传进去的值是符合条件的 所以pre = 1  偶数个奇数 即0个奇数 
}
ll dfs(int pos,int limit,int lead,int pre ,int num)
{
	if(pos<0){//pre和num不相等就是正确的 
		return (pre && !num) || (!pre && num);
	}
	if(!limit && !lead && dp[pos][pre][num] != -1){
		return dp[pos][pre][num];// dp[pos][pre][num] != -1 表示已经计算过了直接返回就好  
	}
	ll tmp = 0;
	int up = limit ? wei[pos] : 9;//看看pos位 最大能取到几 
	for(int i=0;i<=up;i++){
		if(i==0 && lead){//有前导0这一个也是0 那么现在i=0是没有任何意义的 也就是说我们又要像一开始那样  0个奇数了 所以pre= 1 num= 0     
			tmp += dfs(pos-1,0,1,1,0);
		}
		else{
			if((i&1) && pre){//现在和前一个数都是奇数 那么num的奇偶性就要发生变化了 
				tmp += dfs(pos-1,limit && i==up,0,1,num^1);
			}
			if(!(i&1) && !pre){//都是偶数 num的奇偶性发生改变 并且没有前导零 
				tmp += dfs(pos-1,limit && i==up ,0,0,num^1);
			}
			if((i&1) && !pre && num){// 如果说 i是奇数 pre是偶数 num是偶数 已经不符合条件了我们就没有必要向下传递了 如果num是奇数就说明是可以的  但是由于现在这个数和前一个数的奇偶性不一样 连续性就断了 现在连的长度就变成了1 是奇数 num= 1 
				tmp += dfs(pos-1,limit&&i==up , 0, 1, 1);
			}
			if(!(i&1) && pre && !num){//同理 
				tmp += dfs(pos-1,limit &&i==up ,0,0,1);
			}
		}
	}
	if(!limit && !lead){
		dp[pos][pre][num] = tmp;
	}
	return tmp;
}


猜你喜欢

转载自blog.csdn.net/qq_39562286/article/details/80409590