zoukankan      html  css  js  c++  java
  • hdu 5898 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).

    InputFirst line a t,then t cases.every line contains two integers L and R.OutputPrint 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学习题。
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #define MAX 200005
    #define inf 0x3f3f3f3f
    using namespace std;
    long long dp[20][2][2],bound[20];
    long long dfs(int pos,int pre,int ispre,bool lead,bool limit)///pos表示位置 从高位开始  pre表上上一位的1奇0偶性 ispre表示上一位奇偶性连续个数的奇偶性 lead前导0
    {
        if(pos == -1)return (pre ^ ispre);///最低一位也过了判断 最后这一串连续的 奇数或偶数的 个数奇偶性是否满足 满足返回真
        if(!limit && !lead && dp[pos][pre][ispre] != -1)return dp[pos][pre][ispre];///如果没限制 也不是 前导 0 dp当前位置还记录过 直接返回
        int up = (limit ? bound[pos] : 9);///确定当前位的限制 如果上一位到了限制位 那么这一位也需要限制(比如120,百位是1的情况下十位最高是2,百位不足1,十位可以到9)
        long long ans = 0;///记录之后位的满足个数
        for(int i = 0;i <= up;i ++)
        {
            if(lead && !i)ans += dfs(pos - 1,1,0,true,limit && i == up);///前导0 不算在内
            else if(!(i % 2 ^ pre))ans += dfs(pos - 1,pre,ispre ^ 1,false,limit && i == up);///奇偶性与上一位相同
            else if((i % 2 ^ pre) && (pre ^ ispre))ans += dfs(pos - 1,i % 2,1,false,limit && i == up);///奇偶性不同 且上一位奇偶性的连续个数的奇偶性正确 不然没必要继续
        }
        if(!limit && !lead)dp[pos][pre][ispre] = ans;///无限制 无前导0 可以记录 方便下次直接返回
        return ans;
    }
    long long solve(long long t)
    {
        long long c = 0;
        while(t)
        {
            bound[c ++] = t % 10;
            t /= 10;
        }
        return dfs(c - 1,1,0,true,true);///为了能进入下一层 pre 和 ispre不能相同 相当于前导0
    }
    int main()
    {
        long long l,r;
        int n;
        memset(dp,-1,sizeof(dp));
        scanf("%lld",&n);
        for(int i = 1;i <= n;i ++)
        {
            scanf("%lld%lld",&l,&r);
            printf("Case #%d: %lld
    ",i,solve(r) - solve(l - 1));
        }
    }
  • 相关阅读:
    Scala学习笔记(四)—— 数组
    Scala学习笔记(三)—— 方法和函数
    Scala学习笔记(二)——Scala基础
    Scala学习笔记(一)
    HDFS和GFS对比学习
    HDFS原理学习
    c++日历问题
    Mapreduce学习
    c++动态规划解决数塔问题
    C++——数码管
  • 原文地址:https://www.cnblogs.com/8023spz/p/9061378.html
Copyright © 2011-2022 走看看