您的位置:首页 > 其它

2016 ACM/ICPC Asia Regional Shenyang Online HDU 5898 odd-even number

2016-09-19 20:59 489 查看

odd-even number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 343    Accepted Submission(s): 186


[align=left]Problem Description[/align]
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).
 

[align=left]Input[/align]
First line a t,then t cases.every line contains two integers L and R.
 

[align=left]Output[/align]
Print the output for each case on one line in the format as shown below.
 

[align=left]Sample Input[/align]

2
1 100
110 220

 

[align=left]Sample Output[/align]

Case #1: 29
Case #2: 36

 

【题意】统计区间内满足连续奇数个数为偶数且连续偶数为奇数的数的个数。

【解题方法】dp(l,pre,con,fz)表示前l位,最后一位是pre,并且此时这个pre所在的连通块已经有con个了,fz来区分是不是前导零。

【AC 代码】
//
//Created by just_sort 2016/10/6
//Copyright (c) 2016 just_sort.All Rights Reserved
//
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int digit[20];
LL dp[20][2][2][2];
LL dfs(int l,int pre,int con,int fz,bool jud)
{
if(l == 0){
if(pre%2 == 0){
if(con%2 == 0) return 0;
else return 1;
}
else{
if(con%2 == 0) return 1;
else return 0;
}
}
if(!jud && dp[l][pre][con][fz]!=-1) return dp[l][pre][con][fz];
int nex = jud?digit[l]:9;
LL ret = 0;
if(fz){
for(int i = 0; i <= nex; i++){
ret += dfs(l-1,i%2,1,fz&&(i==0),jud&&(i==nex));
}
}
else if((pre+con)%2 == 1){
for(int i = 0; i <= nex; i++){
if((i+pre)%2 == 0){
ret += dfs(l-1,i%2,(con+1)%2,fz&&(i==0),jud&&(i==nex));
}
else{
ret += dfs(l-1,i%2,1,fz&&(i==0),jud&&(i==nex));
}
}
}
else{
for(int i = 0; i <= nex; i++){
if((i+pre)%2==0){
ret += dfs(l-1,i%2,(con+1)%2,fz&&(i==0),jud&&(i==nex));
}
}
}
if(!jud) dp[l][pre][con][fz] = ret;
return ret;
}
LL f(LL num){
int pos = 0;
while(num){
digit[++pos] = num%10;
num /= 10;
}
return dfs(pos,0,1,true,true);
}
int main()
{
int T,ks = 1;
memset(dp,-1,sizeof(dp));
scanf("%d",&T);
while(T--)
{
LL l,r;
scanf("%lld%lld",&l,&r);
printf("Case #%d: %lld\n",ks++,f(r)-f(l-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐