2016沈阳网络赛 odd-even number

odd-even number

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

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
分析:数位dp;
   dp[i][j][k]三维分别代表位置,当前数奇偶性,个数奇偶性;
   注意前导0的特判;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
const int maxn=1e5+10;
const int N=5e4+10;
const int M=N*10*10;
using namespace std;
inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
inline void umax(ll &p,ll q){if(p<q)p=q;}
inline void umin(ll &p,ll q){if(p>q)p=q;}
inline ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,k,t,num[20],pos,cas;
ll dp[20][2][2],p,q;
ll dfs(int pos,int x,int y,int z,int k)
{
    if(pos<0)return k&&(x^y)==1;
    if(z&&k&&dp[pos][x][y]!=-1)return dp[pos][x][y];
    int now=z?9:num[pos],i;
    ll ret=0;
    rep(i,0,now)
    {
        if(k&&(x^(i&1))==1&&(x^y)==0)continue;
        if(!i&&!k)ret+=dfs(pos-1,x,y,z||i<num[pos],k||i);
        else if((i&1)==x)ret+=dfs(pos-1,x,y^1,z||i<num[pos],k||i);
        else ret+=dfs(pos-1,x^1,1,z||i<num[pos],k||i);
    }
    return z&&k?dp[pos][x][y]=ret:ret;
}
ll gao(ll x)
{
    pos=0;
    while(x)num[pos++]=x%10,x/=10;
    return dfs(pos-1,1,0,0,0);
}
int main()
{
    int i,j;
    memset(dp,-1,sizeof(dp));
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld",&p,&q);
        printf("Case #%d: %lld
",++cas,gao(q)-gao(p-1));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dyzll/p/5890598.html